working on padding and cell linespacing

This commit is contained in:
Jörg Prante 2022-01-17 16:39:59 +01:00
parent e7ff6e59ff
commit d7066d586e
21 changed files with 122 additions and 65 deletions

View file

@ -21,6 +21,8 @@ public class HorizontalRuler implements Drawable, Element, WidthRespecting {
private float maxWidth = -1f;
private Position absolutePosition;
public HorizontalRuler(Stroke stroke, Color color) {
super();
this.stroke = stroke;
@ -66,7 +68,16 @@ public class HorizontalRuler implements Drawable, Element, WidthRespecting {
@Override
public Position getAbsolutePosition() {
return null;
return absolutePosition;
}
/**
* Sets the absolute position to render at.
*
* @param absolutePosition the absolute position.
*/
public void setAbsolutePosition(Position absolutePosition) {
this.absolutePosition = absolutePosition;
}
@Override

View file

@ -84,7 +84,7 @@ public class Paragraph extends TextFlow implements Drawable, Element, WidthRespe
public Element add(Element element) {
if (element instanceof TextElement) {
TextElement textElement = (TextElement) element;
addMarkup(textElement.getValue(), textElement.getSize(), textElement.getFont());
addMarkup(textElement.getValue(), textElement.getFontSize(), textElement.getFont());
} else {
throw new UnsupportedOperationException();
}

View file

@ -42,8 +42,8 @@ public class TableElement implements Element, Drawable, Dividable {
table.addColumnOfWidth(width);
}
public void padding(float padding) {
table.padding(padding);
public void padding(float paddingLeft, float paddingRight, float paddingTop, float paddingBottom) {
table.padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
}
public void textColor(Color color) {

View file

@ -8,12 +8,12 @@ public class TextElement implements Element {
private final Font font;
private final float size;
private final float fontsize;
public TextElement(String value, Font font, float size) {
public TextElement(String value, Font font, float fontsize) {
this.value = value;
this.font = font;
this.size = size;
this.fontsize = fontsize;
}
public String getValue() {
@ -24,8 +24,7 @@ public class TextElement implements Element {
return font;
}
public float getSize() {
return size;
public float getFontSize() {
return fontsize;
}
}

View file

@ -29,7 +29,8 @@ public class Engine implements Closeable {
public void executeElements(Settings settings) throws IOException {
execute(settings.getAsSettings("elements"));
for (int i = 0; i < 256; i++) {
// limit to 1000 elements, abort if no element is present
for (int i = 0; i < 1000; i++) {
if (!executeElement(i, settings)) {
break;
}

View file

@ -30,7 +30,15 @@ public class CellCommand implements Command {
public void execute(Engine engine, State state, Settings settings) throws IOException {
if (settings.containsSetting("value")) {
TextCell.Builder cell = TextCell.builder();
cell.padding(settings.getAsFloat("padding", 0f));
if (settings.containsSetting("padding")) {
String padding = settings.get("padding", "0 0 0 0");
String[] paddings = padding.split(" ");
float paddingLeft = Float.parseFloat(paddings[0]);
float paddingRight = Float.parseFloat(paddings[1]);
float paddingTop = Float.parseFloat(paddings[2]);
float paddingBottom = Float.parseFloat(paddings[3]);
cell.padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
}
cell.text(settings.get("value"));
cell.fontSize(settings.getAsFloat("fontsize", 11.0f));
Document document = state.getDocument();
@ -75,9 +83,13 @@ public class CellCommand implements Command {
cell.paragraph(paragraph);
String value = settings.get("markup");
float size = settings.getAsFloat("fontsize", 11.0f);
Float lineSpacing = settings.getAsFloat("linespacing", -1f);
Document document = state.getDocument();
Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document);
cell.add(new Markup().setValue(value).setFont(font).setFontSize(size));
if (lineSpacing != null && lineSpacing >= 0f) {
cell.lineSpacing(lineSpacing);
}
state.elements.peek().add(cell.build());
}
}

View file

@ -5,13 +5,16 @@ import org.xbib.graphics.pdfbox.layout.element.HorizontalRuler;
import org.xbib.graphics.pdfbox.layout.element.scripting.Engine;
import org.xbib.graphics.pdfbox.layout.element.scripting.State;
import org.xbib.graphics.pdfbox.layout.shape.Stroke;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.settings.Settings;
import java.awt.Color;
import java.io.IOException;
import java.util.Locale;
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
public class HorizontalrulerCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
Stroke.StrokeBuilder strokeBuilder = Stroke.builder()
@ -23,6 +26,12 @@ public class HorizontalrulerCommand implements Command {
}
Color color = ColorFactory.web(settings.get("color", "black"));
HorizontalRuler horizontalRuler = new HorizontalRuler(strokeBuilder.build(), color);
if (settings.containsSetting("x") && settings.containsSetting("y")) {
horizontalRuler.setAbsolutePosition(new Position(mmToPt(settings.getAsFloat("x", 0f)), mmToPt(settings.getAsFloat("y", 0f))));
}
if (settings.containsSetting("width")) {
horizontalRuler.setMaxWidth(mmToPt(settings.getAsFloat("width", -1f)));
}
state.elements.peek().add(horizontalRuler);
}
}

View file

@ -27,6 +27,9 @@ public class ParagraphCommand implements Command {
if (settings.containsSetting("alignment")) {
paragraph.setAlignment(Alignment.valueOf(settings.get("alignment", "left").toUpperCase(Locale.ROOT)));
}
if (settings.containsSetting("linespacing")) {
paragraph.setLineSpacing(settings.getAsFloat("linespacing", -1f));
}
state.elements.push(paragraph);
engine.executeElements(settings);
state.elements.pop();

View file

@ -21,7 +21,15 @@ 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));
if (settings.containsSetting("padding")) {
String padding = settings.get("padding", "0 0 0 0");
String[] paddings = padding.split(" ");
float paddingLeft = Float.parseFloat(paddings[0]);
float paddingRight = Float.parseFloat(paddings[1]);
float paddingTop = Float.parseFloat(paddings[2]);
float paddingBottom = Float.parseFloat(paddings[3]);
row.padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
}
row.fontSize(settings.getAsFloat("fontsize", 11.0f));
Document document = state.getDocument();
row.font(Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document));

View file

@ -22,10 +22,18 @@ public class TableCommand implements Command {
tableElement.addColumnOfWidth(mmToPt(Float.parseFloat(width)));
}
}
if (settings.containsSetting("x") && settings.containsSetting("y")) {
tableElement.setAbsolutePosition(new Position(mmToPt(settings.getAsFloat("x", 0f)), mmToPt(settings.getAsFloat("y", 0f))));
}
if (settings.containsSetting("padding")) {
String padding = settings.get("padding", "0 0 0 0");
String[] paddings = padding.split(" ");
float paddingLeft = Float.parseFloat(paddings[0]);
float paddingRight = Float.parseFloat(paddings[1]);
float paddingTop = Float.parseFloat(paddings[2]);
float paddingBottom = Float.parseFloat(paddings[3]);
tableElement.padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
}
state.elements.push(tableElement);
engine.executeElements(settings);
state.elements.pop();

View file

@ -43,5 +43,4 @@ public class Markup implements ParagraphProcessor {
float fontSize = getFontSize() != null ? getFontSize() : parameters.getFontSize();
paragraph.addMarkup(getValue(), fontSize, font);
}
}

View file

@ -34,8 +34,6 @@ public class ParagraphCell extends AbstractCell {
@Override
public void setWidth(float width) {
super.setWidth(width);
//while (getCellParagraph().getParagraph().removeLast() != null) {
//}
for (ParagraphProcessor p : getCellParagraph().getParagraphProcessors()) {
try {
p.process(getCellParagraph().getParagraph(), getParameters());
@ -94,6 +92,8 @@ public class ParagraphCell extends AbstractCell {
private Paragraph paragraph;
private float lineSpacing = 1f;
private final List<ParagraphProcessor> processors;
private Builder() {
@ -116,6 +116,11 @@ public class ParagraphCell extends AbstractCell {
return this;
}
public Builder lineSpacing(float lineSpacing) {
this.lineSpacing = lineSpacing;
return this;
}
public Builder add(ParagraphProcessor processor) {
this.processors.add(processor);
return this;
@ -126,6 +131,7 @@ public class ParagraphCell extends AbstractCell {
cell.setParameters(parameters);
cell.setColSpan(colSpan);
cell.setRowSpan(rowSpan);
cell.setLineSpacing(lineSpacing);
cell.setCellParagraph(new CellParagraph(paragraph, processors));
return cell;
}

View file

@ -134,11 +134,11 @@ public class Row {
return this;
}
public Builder padding(final float padding) {
parameters.setPaddingTop(padding);
parameters.setPaddingBottom(padding);
parameters.setPaddingLeft(padding);
parameters.setPaddingRight(padding);
public Builder padding(float paddingLeft, float paddingRight, float paddingTop, float paddingBottom) {
parameters.setPaddingLeft(paddingLeft);
parameters.setPaddingRight(paddingRight);
parameters.setPaddingTop(paddingTop);
parameters.setPaddingBottom(paddingBottom);
return this;
}

View file

@ -252,11 +252,11 @@ public class Table {
return this;
}
public Builder padding(final float padding) {
parameters.setPaddingTop(padding);
parameters.setPaddingBottom(padding);
parameters.setPaddingLeft(padding);
parameters.setPaddingRight(padding);
public Builder padding(float paddingLeft, float paddingRight, float paddingTop, float paddingBottom) {
parameters.setPaddingLeft(paddingLeft);
parameters.setPaddingRight(paddingRight);
parameters.setPaddingTop(paddingTop);
parameters.setPaddingBottom(paddingBottom);
return this;
}

View file

@ -116,11 +116,11 @@ public class TextCell extends AbstractTextCell {
.borderStyleTop(style);
}
public Builder padding(final float padding) {
return this.paddingTop(padding)
.paddingBottom(padding)
.paddingLeft(padding)
.paddingRight(padding);
public Builder padding(float paddingLeft, float paddingRight, float paddingTop, float paddingBottom) {
return this.paddingTop(paddingTop)
.paddingBottom(paddingBottom)
.paddingLeft(paddingLeft)
.paddingRight(paddingRight);
}
public Builder paddingTop(final float padding) {

View file

@ -71,15 +71,15 @@ public class TextFlow implements TextSequence, WidthRespecting {
}
public void addText(String text, float fontSize, Font font) {
add(TextFlowUtil.createTextFlow(text, new FontDescriptor(font, fontSize)));
add(TextFlowUtil.createTextFlow(text, new FontDescriptor(font, fontSize), lineSpacing));
}
public void addMarkup(String markup, FontDescriptor fontDescriptor) {
add(TextFlowUtil.createTextFlowFromMarkup(markup, fontDescriptor));
add(TextFlowUtil.createTextFlowFromMarkup(markup, fontDescriptor, lineSpacing));
}
public void addMarkup(String markup, float fontSize, Font font) {
add(TextFlowUtil.createTextFlowFromMarkup(markup, new FontDescriptor(font, fontSize)));
add(TextFlowUtil.createTextFlowFromMarkup(markup, new FontDescriptor(font, fontSize), lineSpacing));
}
public void addIndent(String label, float indentWidth, SpaceUnit indentUnit, float fontsize, Font font) {
@ -262,5 +262,4 @@ public class TextFlow implements TextSequence, WidthRespecting {
public String toString() {
return "TextFlow [text=" + text + "]";
}
}

View file

@ -15,9 +15,8 @@ import java.util.regex.Matcher;
public class TextFlowUtil {
public static TextFlow createTextFlow(String text, FontDescriptor descriptor) {
final Iterable<CharSequence> parts = fromPlainText(text);
return createTextFlow(parts, descriptor);
public static TextFlow createTextFlow(String text, FontDescriptor descriptor, float linespacing) {
return createTextFlow(fromPlainText(text), descriptor, linespacing);
}
/**
@ -49,11 +48,11 @@ public class TextFlowUtil {
*
* @param markup the markup text.
* @param descriptor the font size to use, and the font.
* @param linespacing the line spacing
* @return the created text flow.
*/
public static TextFlow createTextFlowFromMarkup(String markup, FontDescriptor descriptor) {
final Iterable<CharSequence> parts = fromMarkup(markup);
return createTextFlow(parts, descriptor);
public static TextFlow createTextFlowFromMarkup(String markup, FontDescriptor descriptor, float linespacing) {
return createTextFlow(fromMarkup(markup), descriptor, linespacing);
}
/**
@ -61,10 +60,12 @@ public class TextFlowUtil {
*
* @param parts the parts to create the text flow from.
* @param descriptor the font size to use.
* @param linespacing the line spacing
* @return the created text flow.
*/
protected static TextFlow createTextFlow(Iterable<CharSequence> parts, FontDescriptor descriptor) {
final TextFlow result = new TextFlow();
protected static TextFlow createTextFlow(Iterable<CharSequence> parts, FontDescriptor descriptor, float linespacing) {
final TextFlow textFlow = new TextFlow();
textFlow.setLineSpacing(linespacing);
boolean bold = false;
boolean italic = false;
Color color = Color.black;
@ -74,7 +75,7 @@ public class TextFlowUtil {
for (final CharSequence fragment : parts) {
if (fragment instanceof ControlCharacter) {
if (fragment instanceof ControlCharacters.NewLineControlCharacter) {
result.add(new NewLine(descriptor));
textFlow.add(new NewLine(descriptor));
}
if (fragment instanceof ControlCharacters.BoldControlCharacter) {
bold = !bold;
@ -105,7 +106,7 @@ public class TextFlowUtil {
IndentCharacters.IndentCharacter currentIndent = (IndentCharacters.IndentCharacter) fragment;
if (currentIndent.getLevel() == 0) {
indentStack.clear();
result.add(Indent.UNINDENT);
textFlow.add(Indent.UNINDENT);
} else {
IndentCharacters.IndentCharacter last = null;
while (!indentStack.isEmpty()
@ -120,7 +121,7 @@ public class TextFlowUtil {
indentStack.push(currentIndent);
FontDescriptor fontDescriptor =
new FontDescriptor(descriptor.getFont(), descriptor.getSize(), bold, italic);
result.add(currentIndent.createNewIndent(fontDescriptor, color));
textFlow.add(currentIndent.createNewIndent(fontDescriptor, color));
}
}
} else {
@ -134,16 +135,16 @@ public class TextFlowUtil {
if (annotationMap.isEmpty()) {
StyledText styledText = new StyledText(fragment.toString(), fontDescriptor,
color, baselineOffset, 0, 0);
result.add(styledText);
textFlow.add(styledText);
} else {
AnnotatedStyledText styledText =
new AnnotatedStyledText(fragment.toString(), fontDescriptor,
color, baselineOffset, 0, 0, annotationMap.values());
result.add(styledText);
textFlow.add(styledText);
}
}
}
return result;
return textFlow;
}
/**

View file

@ -98,7 +98,7 @@ public class CustomRendererTest {
public void afterPage(RenderContext renderContext) {
String content = String.format("Section %s, Page %s", sectionNumber, renderContext.getPageIndex() + 1);
FontDescriptor fontDescriptor = new FontDescriptor(BaseFont.TIMES, 11);
TextFlow text = TextFlowUtil.createTextFlow(content, fontDescriptor);
TextFlow text = TextFlowUtil.createTextFlow(content, fontDescriptor, 1.2f);
float offset = renderContext.getPageFormat().getMarginLeft() +
TextSequenceUtil.getOffset(text, renderContext.getWidth(), Alignment.RIGHT);
text.drawText(renderContext.getContentStream(), new Position(

View file

@ -48,7 +48,7 @@ public class ListenerTest {
public void afterPage(RenderContext renderContext) {
String content = String.format("Page %s", renderContext.getPageIndex() + 1);
FontDescriptor fontDescriptor = new FontDescriptor(BaseFont.HELVETICA, 11);
TextFlow text = TextFlowUtil.createTextFlow(content, fontDescriptor);
TextFlow text = TextFlowUtil.createTextFlow(content, fontDescriptor, 1.2f);
float offset = renderContext.getPageFormat().getMarginLeft()
+ TextSequenceUtil.getOffset(text,
renderContext.getWidth(), Alignment.RIGHT);

View file

@ -54,7 +54,7 @@ public class LowLevelText {
TextFlow text = TextFlowUtil.createTextFlowFromMarkup(
"Hello *bold _italic bold-end* italic-end_. Eirmod\ntempor invidunt ut \\*labore",
new FontDescriptor(BaseFont.TIMES, 11));
new FontDescriptor(BaseFont.TIMES, 11), 1.2f);
text.addText("Spongebob", 11, BaseFont.COURIER);
text.addText(" is ", 20, BaseFont.HELVETICA);
text.addText("cool", 7, BaseFont.HELVETICA);

View file

@ -5,7 +5,8 @@
"elements": [
{
"type": "image",
"scale": 0.25,
"scalex": 0.2,
"scaley": 0.2,
"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=="
},
{
@ -25,7 +26,7 @@
"elements": [
{
"type": "text",
"value": "Hello World",
"value": "Hello World 1",
"size": 24,
"font": "helvetica"
}
@ -36,7 +37,7 @@
"elements": [
{
"type": "text",
"value": "Hello World",
"value": "Hello World 2",
"size": 24,
"font": "helvetica"
}
@ -47,7 +48,7 @@
"elements": [
{
"type": "text",
"value": "Hello World",
"value": "Hello World 3",
"size": 24,
"font": "helvetica"
}
@ -61,7 +62,7 @@
"elements": [
{
"type": "text",
"value": "Hello World",
"value": "Hello World 4",
"size": 16,
"font": "notosans"
}
@ -72,7 +73,7 @@
"elements": [
{
"type": "text",
"value": "Hello World",
"value": "Hello World 5",
"size": 20,
"font": "notosans"
}
@ -80,7 +81,7 @@
},
{
"type": "table",
"padding": 10,
"padding": "10 10 10 10",
"columnwidths": "50 50 50",
"elements": [
{
@ -121,7 +122,7 @@
},
{
"type": "table",
"columnwidths": "80 80 80",
"columnwidths": "60 40 20",
"elements": [
{
"type": "row",
@ -146,19 +147,19 @@
{
"type": "cell",
"value": "Cell 4",
"padding": 5,
"padding": "5 5 5 5",
"borderwidth": 0.5
},
{
"type": "cell",
"value": "Cell 5",
"padding": 5,
"padding": "5 5 5 5",
"borderwidth": 0.5
},
{
"type": "cell",
"value": "Cell 6",
"padding": 5,
"padding": "5 5 5 5",
"borderwidth": 0.5
}
]
@ -170,7 +171,7 @@
"elements": [
{
"type": "text",
"value": "Hello World",
"value": "Hello World 6",
"size": 20,
"font": "notosans"
}