use one element stack

This commit is contained in:
Jörg Prante 2021-12-08 00:19:18 +01:00
parent 8056505e4d
commit 6711aa9cec
36 changed files with 152 additions and 63 deletions

View file

@ -26,5 +26,4 @@ public class ControlElement implements Element {
public String toString() {
return "ControlElement [NEWPAGE=" + NEWPAGE + ", name=" + name + "]";
}
}

View file

@ -13,7 +13,9 @@ import java.io.IOException;
public class Cutter implements Dividable, Drawable {
private final Drawable undividable;
private final float viewPortY;
private final float viewPortHeight;
public Cutter(Drawable undividableElement) throws IOException {

View file

@ -45,7 +45,5 @@ public interface Dividable {
public Drawable getTail() {
return tail;
}
}
}

View file

@ -27,7 +27,7 @@ import java.util.Map.Entry;
/**
* The central class for creating a document.
*/
public class Document implements Closeable, RenderListener {
public class Document implements Element, Closeable, RenderListener {
private final List<Entry<Element, LayoutHint>> elements = new ArrayList<>();
@ -141,8 +141,10 @@ public class Document implements Closeable, RenderListener {
*
* @param element the element to add
*/
public void add(Element element) {
@Override
public Element add(Element element) {
add(element, new VerticalLayoutHint());
return this;
}
/**

View file

@ -5,4 +5,7 @@ package org.xbib.graphics.pdfbox.layout.elements;
*/
public interface Element {
default Element add(Element element) {
throw new UnsupportedOperationException();
}
}

View file

@ -77,7 +77,7 @@ public class Frame implements Element, Drawable, WidthRespecting, Dividable {
*/
public Frame(final Drawable inner, final Float width, final Float height) {
this(width, height);
add(inner);
addDrawable(inner);
}
/**
@ -90,7 +90,7 @@ public class Frame implements Element, Drawable, WidthRespecting, Dividable {
* @param height the height to constrain the border-box of the frame to, or
* <code>null</code>.
*/
public Frame(final Float width, final Float height) {
public Frame(Float width, Float height) {
this.givenWidth = width;
this.givenHeight = height;
}
@ -100,7 +100,7 @@ public class Frame implements Element, Drawable, WidthRespecting, Dividable {
*
* @param drawable the drawable
*/
public void add(final Drawable drawable) {
public void addDrawable(Drawable drawable) {
innerList.add(drawable);
}
@ -580,13 +580,13 @@ public class Frame implements Element, Drawable, WidthRespecting, Dividable {
first.addAll(dividedList.getHead());
}
if (divided != null) {
first.add(divided.getFirst());
first.addDrawable(divided.getFirst());
}
// create tail sub frame
Frame tail = new Frame(getGivenWidth(), tailHeight);
copyAllButInnerAndSizeTo(tail);
if (divided != null) {
tail.add(divided.getTail());
tail.addDrawable(divided.getTail());
}
if (dividedList.getTail() != null) {
tail.addAll(dividedList.getTail());
@ -622,12 +622,14 @@ public class Frame implements Element, Drawable, WidthRespecting, Dividable {
}
public static class DividedList {
private final List<Drawable> head;
private final Drawable drawableToDivide;
private final List<Drawable> tail;
public DividedList(List<Drawable> head, Drawable drawableToDivide,
List<Drawable> tail) {
public DividedList(List<Drawable> head, Drawable drawableToDivide, List<Drawable> tail) {
this.head = head;
this.drawableToDivide = drawableToDivide;
this.tail = tail;

View file

@ -92,5 +92,4 @@ public class HorizontalRuler implements Drawable, Element, WidthRespecting {
public Drawable removeLeadingEmptyVerticalSpace() {
return this;
}
}

View file

@ -80,4 +80,14 @@ public class Paragraph extends TextFlow implements Drawable, Element, WidthRespe
return new Paragraph();
}
@Override
public Element add(Element element) {
if (element instanceof TextElement) {
TextElement textElement = (TextElement) element;
addMarkup(textElement.getValue(), textElement.getSize(), textElement.getFont());
} else {
throw new UnsupportedOperationException();
}
return this;
}
}

View file

@ -24,8 +24,15 @@ public class TableElement implements Element, Drawable, Dividable {
this.table = Table.builder();
}
public void add(Row row) {
table.addRow(row);
@Override
public Element add(Element element) {
if (element instanceof Row.Builder) {
Row row = ((Row.Builder) element).build();
table.addRow(row);
} else {
throw new UnsupportedOperationException();
}
return this;
}
public void addColumnOfWidth(float width) {

View file

@ -0,0 +1,31 @@
package org.xbib.graphics.pdfbox.layout.elements;
import org.xbib.graphics.pdfbox.layout.font.Font;
public class TextElement implements Element {
private final String value;
private final Font font;
private final float size;
public TextElement(String value, Font font, float size) {
this.value = value;
this.font = font;
this.size = size;
}
public String getValue() {
return value;
}
public Font getFont() {
return font;
}
public float getSize() {
return size;
}
}

View file

@ -57,5 +57,4 @@ public class VerticalSpacer implements Drawable, Element, Dividable {
public Drawable removeLeadingEmptyVerticalSpace() {
return this;
}
}

View file

@ -264,5 +264,4 @@ public class VerticalLayout implements Layout {
}
return drawable;
}
}

View file

@ -1,24 +1,26 @@
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 org.xbib.graphics.pdfbox.layout.elements.Element;
import java.util.Collection;
import java.util.List;
import java.util.Stack;
import java.util.stream.Collectors;
public class State {
public Stack<Document> documents = new Stack<>();
public Stack<Element> elements = new Stack<>();
public Stack<Paragraph> paragraphs = new Stack<>();
public Document getDocument() {
List<Document> list = getDocuments();
int size = list.size();
return size > 0 ? list.get(size - 1) : null;
}
public Stack<TableElement> tables = new Stack<>();
public Stack<Row.Builder> rows = new Stack<>();
public Collection<Document> getDocuments() {
return documents;
public List<Document> getDocuments() {
return elements.stream()
.filter(e -> e instanceof Document)
.map(e -> (Document) e)
.collect(Collectors.toList());
}
}

View file

@ -38,6 +38,6 @@ public class BarcodeCommand implements Command {
if (settings.containsSetting("scale")) {
element.setScale(settings.getAsFloat("scale", element.getScale()));
}
state.documents.peek().add(element);
state.elements.peek().add(element);
}
}

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.color.ColorFactory;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.Fonts;
import org.xbib.graphics.pdfbox.layout.script.Engine;
@ -21,7 +22,8 @@ public class CellCommand implements Command {
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());
Document document = state.getDocument();
Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document);
cell.font(font);
cell.padding(settings.getAsFloat("padding", 0f));
Color color = ColorFactory.web(settings.get("color", "black"));
@ -39,6 +41,6 @@ public class CellCommand implements Command {
cell.borderStyle(styleInterface);
cell.colSpan(settings.getAsInt("colspan", 1));
cell.rowSpan(settings.getAsInt("rowspan", 1));
state.rows.peek().add(cell.build());
state.elements.peek().add(cell.build());
}
}

View file

@ -12,6 +12,6 @@ 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);
state.elements.peek().add(columnLayout);
}
}

View file

@ -14,8 +14,6 @@ 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()
@ -42,7 +40,7 @@ public class DocumentCommand implements Command {
if (settings.containsSetting("title")) {
document.setTitle(settings.get("title"));
}
state.documents.push(document);
state.elements.push(document);
engine.executeElements(settings);
}
}

View file

@ -0,0 +1,28 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.color.ColorFactory;
import org.xbib.graphics.pdfbox.layout.elements.Frame;
import org.xbib.graphics.pdfbox.layout.script.Engine;
import org.xbib.graphics.pdfbox.layout.script.State;
import org.xbib.settings.Settings;
import java.awt.Color;
import java.io.IOException;
public class FrameCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
Frame frame = new Frame();
//frame.setPadding(settings.getAsFloat("padding", 0f));
if (settings.containsSetting("backgroundcolor")) {
Color backgroundColor = ColorFactory.web(settings.get("backgroundcolor", "black"));
frame.setBackgroundColor(backgroundColor);
}
if (settings.containsSetting("bordercolor")) {
Color borderColor = ColorFactory.web(settings.get("bordercolor", "black"));
frame.setBorderColor(borderColor);
}
state.elements.peek().add(frame);
}
}

View file

@ -23,6 +23,6 @@ public class HorizontalrulerCommand implements Command {
}
Color color = ColorFactory.web(settings.get("color", "black"));
HorizontalRuler horizontalRuler = new HorizontalRuler(strokeBuilder.build(), color);
state.documents.peek().add(horizontalRuler);
state.elements.peek().add(horizontalRuler);
}
}

View file

@ -35,6 +35,6 @@ public class ImageCommand implements Command {
float margintop = Float.parseFloat(margins[2]);
float marginbottom = Float.parseFloat(margins[3]);
VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, true);
state.documents.peek().add(imageElement, verticalLayoutHint);
state.elements.peek().add(imageElement);
}
}

View file

@ -12,6 +12,6 @@ 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);
state.elements.peek().add(markPosition);
}
}

View file

@ -12,6 +12,6 @@ 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);
state.elements.peek().add(movePosition);
}
}

View file

@ -11,6 +11,6 @@ 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);
state.elements.peek().add(controlElement);
}
}

View file

@ -11,6 +11,6 @@ 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);
state.elements.peek().add(controlElement);
}
}

View file

@ -15,17 +15,18 @@ public class ParagraphCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
Paragraph paragraph = new Paragraph();
state.paragraphs.push(paragraph);
if (settings.containsSetting("x") && settings.containsSetting("y")) {
paragraph.setAbsolutePosition(new Position(settings.getAsFloat("x", 0f), settings.getAsFloat("y", 0f)));
}
if (settings.containsSetting("width")) {
paragraph.setMaxWidth(settings.getAsFloat("width", state.documents.peek().getPageWidth()));
paragraph.setMaxWidth(settings.getAsFloat("width", 0f));
}
if (settings.containsSetting("alignment")) {
paragraph.setAlignment(Alignment.valueOf(settings.get("alignment", "left").toUpperCase(Locale.ROOT)));
}
state.documents.peek().add(paragraph);
state.elements.push(paragraph);
engine.executeElements(settings);
state.elements.pop();
state.elements.peek().add(paragraph);
}
}

View file

@ -47,6 +47,6 @@ public class PathCommand implements Command {
strokeBuilder.dashPattern(new Stroke.DashPattern(settings.getAsFloat("dash", 1f)));
}
Color color = ColorFactory.web(settings.get("color", "black"));
state.documents.peek().add(new PathElement(path, strokeBuilder.build(), color, position));
state.elements.peek().add(new PathElement(path, strokeBuilder.build(), color, position));
}
}

View file

@ -12,6 +12,6 @@ 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);
state.elements.peek().add(resetPosition);
}
}

View file

@ -13,9 +13,9 @@ public class RowCommand implements Command {
public void execute(Engine engine, State state, Settings settings) throws IOException {
Row.Builder row = Row.builder();
row.padding(settings.getAsFloat("padding", 0f));
state.rows.push(row);
state.elements.push(row);
engine.executeElements(settings);
state.tables.peek().add(row.build());
state.elements.pop();
state.elements.peek().add(row);
}
}

View file

@ -12,6 +12,6 @@ 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);
state.elements.peek().add(setPosition);
}
}

View file

@ -11,7 +11,6 @@ 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");
@ -19,8 +18,9 @@ public class TableCommand implements Command {
tableElement.addColumnOfWidth(Float.parseFloat(columnWidth));
}
}
state.documents.peek().add(tableElement);
state.tables.push(tableElement);
state.elements.push(tableElement);
engine.executeElements(settings);
state.elements.pop();
state.elements.peek().add(tableElement);
}
}

View file

@ -1,5 +1,7 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.TextElement;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.Fonts;
import org.xbib.graphics.pdfbox.layout.script.Engine;
@ -14,7 +16,8 @@ public class TextCommand implements Command {
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").toUpperCase(Locale.ROOT)).getFont(state.documents.peek());
state.paragraphs.peek().addMarkup(value, size, font);
Document document = state.getDocument();
Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document);
state.elements.peek().add(new TextElement(value, font, size));
}
}

View file

@ -11,6 +11,6 @@ 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);
state.elements.peek().add(verticalSpacer);
}
}

View file

@ -1,10 +1,11 @@
package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.elements.Element;
import org.xbib.graphics.pdfbox.layout.table.render.AbstractCellRenderer;
import org.xbib.graphics.pdfbox.layout.table.render.Renderer;
import java.awt.Color;
public abstract class AbstractCell {
public abstract class AbstractCell implements Element {
private static final float DEFAULT_MIN_HEIGHT = 10f;

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.elements.Element;
import org.xbib.graphics.pdfbox.layout.font.Font;
import java.awt.Color;
@ -89,7 +90,7 @@ public class Row {
return new Builder();
}
public static class Builder {
public static class Builder implements Element {
private final List<AbstractCell> cells = new ArrayList<>();
@ -98,8 +99,9 @@ public class Row {
private Builder() {
}
public Builder add(final AbstractCell cell) {
cells.add(cell);
@Override
public Builder add(Element element) {
cells.add((AbstractCell) element);
return this;
}

View file

@ -76,7 +76,7 @@ public class FramesTest {
paragraph = new Paragraph();
paragraph.addMarkup(text2, 11, BaseFont.TIMES);
paragraph.addMarkup(text2, 11, BaseFont.TIMES);
frame.add(paragraph);
frame.addDrawable(paragraph);
document.add(frame);
document.render().save(new FileOutputStream("build/frames.pdf")).close();
}

View file

@ -1,6 +1,6 @@
{
"type": "document",
"margin": "10 10 10 10",
"margin": "20 20 20 20",
"author": "Jörg Prante",
"elements": [
{
@ -80,6 +80,7 @@
},
{
"type": "table",
"padding": 10,
"columnwidths": "50 50 50",
"elements": [
{