table cells use font descriptor now

This commit is contained in:
Jörg Prante 2023-08-26 09:38:03 +02:00
parent 26d8f2756a
commit b62aacfe59
20 changed files with 289 additions and 266 deletions

View file

@ -1,5 +1,5 @@
group = org.xbib.graphics group = org.xbib.graphics
name = graphics name = graphics
version = 4.5.4 version = 4.5.6
org.gradle.warning.mode = ALL org.gradle.warning.mode = ALL

View file

@ -6,6 +6,7 @@ import org.xbib.graphics.pdfbox.layout.element.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.element.scripting.Engine; import org.xbib.graphics.pdfbox.layout.element.scripting.Engine;
import org.xbib.graphics.pdfbox.layout.element.scripting.State; import org.xbib.graphics.pdfbox.layout.element.scripting.State;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.table.BorderStyle; import org.xbib.graphics.pdfbox.layout.table.BorderStyle;
import org.xbib.graphics.pdfbox.layout.table.BorderStyleInterface; import org.xbib.graphics.pdfbox.layout.table.BorderStyleInterface;
import org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment; import org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment;
@ -19,6 +20,8 @@ import org.xbib.settings.Settings;
import java.awt.Color; import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt; import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
@ -39,10 +42,18 @@ public class CellCommand implements Command {
cell.padding(paddingLeft, paddingRight, paddingTop, paddingBottom); cell.padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
} }
cell.text(settings.get("text")); cell.text(settings.get("text"));
cell.fontSize(settings.getAsFloat("fontsize", 11.0f));
Document document = state.getDocument(); Document document = state.getDocument();
Font font = document.getFont(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)); List<Font> list = new ArrayList<>();
cell.font(font); for (String fontName : settings.getAsArray("font")) {
Font font = document.getFont(fontName);
if (font == null) {
throw new IllegalArgumentException("font not specified in document: " + fontName);
} else {
list.add(font);
}
}
float fontSize = settings.getAsFloat("fontsize", 11.0f);
cell.fontDescriptor(new FontDescriptor(list, fontSize));
Color color = ColorFactory.web(settings.get("color", "black")); Color color = ColorFactory.web(settings.get("color", "black"));
cell.textColor(color); cell.textColor(color);
if (settings.containsSetting("backgroundcolor")) { if (settings.containsSetting("backgroundcolor")) {
@ -84,10 +95,11 @@ public class CellCommand implements Command {
paragraph.setLineSpacing(linespacing); paragraph.setLineSpacing(linespacing);
cell.paragraph(paragraph); cell.paragraph(paragraph);
String value = settings.get("markup"); String value = settings.get("markup");
float size = settings.getAsFloat("fontsize", 11.0f); List<Font> list = new ArrayList<>();
Document document = state.getDocument(); for (String fontName : settings.getAsArray("font")) {
Font font = document.getFont(settings.get("font", "helvetica")); list.add(state.getDocument().getFont(fontName));
cell.add(new Markup().setValue(value).setFont(font).setFontSize(size)); }
cell.add(new Markup().setValue(value).setFontDescriptor(new FontDescriptor(list, settings.getAsFloat("fontsize", 11.0f))));
cell.lineSpacing(linespacing); cell.lineSpacing(linespacing);
state.getElements().peek().add(cell.build()); state.getElements().peek().add(cell.build());
} }

View file

@ -1,9 +1,10 @@
package org.xbib.graphics.pdfbox.layout.element.scripting.command; package org.xbib.graphics.pdfbox.layout.element.scripting.command;
import org.xbib.graphics.pdfbox.layout.color.ColorFactory; import org.xbib.graphics.pdfbox.layout.color.ColorFactory;
import org.xbib.graphics.pdfbox.layout.element.Document;
import org.xbib.graphics.pdfbox.layout.element.scripting.Engine; import org.xbib.graphics.pdfbox.layout.element.scripting.Engine;
import org.xbib.graphics.pdfbox.layout.element.scripting.State; import org.xbib.graphics.pdfbox.layout.element.scripting.State;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.table.BorderStyle; import org.xbib.graphics.pdfbox.layout.table.BorderStyle;
import org.xbib.graphics.pdfbox.layout.table.BorderStyleInterface; import org.xbib.graphics.pdfbox.layout.table.BorderStyleInterface;
import org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment; import org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment;
@ -13,6 +14,8 @@ import org.xbib.settings.Settings;
import java.awt.Color; import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale; import java.util.Locale;
public class RowCommand implements Command { public class RowCommand implements Command {
@ -29,9 +32,18 @@ public class RowCommand implements Command {
float paddingBottom = Float.parseFloat(paddings[3]); float paddingBottom = Float.parseFloat(paddings[3]);
row.padding(paddingLeft, paddingRight, paddingTop, paddingBottom); row.padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
} }
row.fontSize(settings.getAsFloat("fontsize", 11.0f)); List<Font> list = new ArrayList<>();
Document document = state.getDocument(); for (String fontName : settings.getAsArray("font")) {
row.font(document.getFont(settings.get("font", "helvetica"))); Font font = state.getDocument().getFont(fontName);
if (font == null) {
throw new IllegalArgumentException("font not specified in document: " + fontName);
} else {
list.add(font);
}
list.add(font);
}
float fontSize = settings.getAsFloat("fontsize", 11.0f);
row.fontDescriptor(new FontDescriptor(list, fontSize));
Color color = ColorFactory.web(settings.get("color", "black")); Color color = ColorFactory.web(settings.get("color", "black"));
row.textColor(color); row.textColor(color);
if (settings.containsSetting("backgroundcolor")) { if (settings.containsSetting("backgroundcolor")) {

View file

@ -26,6 +26,10 @@ public class FontDescriptor {
public FontDescriptor(List<Font> fonts, float size, boolean bold, boolean italic) { public FontDescriptor(List<Font> fonts, float size, boolean bold, boolean italic) {
this.fonts = fonts; this.fonts = fonts;
// we do not accept null fonts
for (Font font : fonts) {
Objects.requireNonNull(font, "no null font allowed");
}
this.size = size; this.size = size;
this.bold = bold; this.bold = bold;
this.italic = italic; this.italic = italic;

View file

@ -1,6 +1,6 @@
package org.xbib.graphics.pdfbox.layout.table; package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.util.PdfUtil; import org.xbib.graphics.pdfbox.layout.util.PdfUtil;
import java.awt.Color; import java.awt.Color;
@ -18,12 +18,8 @@ public abstract class AbstractTextCell extends AbstractCell {
return Math.max((getVerticalPadding() + getTextHeight()), super.getMinHeight()); return Math.max((getVerticalPadding() + getTextHeight()), super.getMinHeight());
} }
public Font getFont() { public FontDescriptor getFontDescriptor() {
return parameters.getFont(); return parameters.getFontDescriptor();
}
public Float getFontSize() {
return parameters.getFontSize();
} }
public Color getTextColor() { public Color getTextColor() {
@ -44,9 +40,9 @@ public abstract class AbstractTextCell extends AbstractCell {
if (this.textHeight != null) { if (this.textHeight != null) {
return this.textHeight; return this.textHeight;
} }
this.textHeight = PdfUtil.getFontHeight(getFont(), getFontSize()); this.textHeight = PdfUtil.getFontHeight(getText(), getFontDescriptor());
if (parameters.isWordBreak()) { if (parameters.isWordBreak()) {
final int size = PdfUtil.getOptimalTextBreakLines(getText(), getFont(), getFontSize(), getMaxWidth()).size(); final int size = PdfUtil.getOptimalTextBreakLines(getText(), getFontDescriptor(), getMaxWidth()).size();
final float heightOfTextLines = size * this.textHeight; final float heightOfTextLines = size * this.textHeight;
final float heightOfLineSpacing = (size - 1) * this.textHeight * getLineSpacing(); final float heightOfLineSpacing = (size - 1) * this.textHeight * getLineSpacing();
this.textHeight = heightOfTextLines + heightOfLineSpacing; this.textHeight = heightOfTextLines + heightOfLineSpacing;
@ -56,12 +52,12 @@ public abstract class AbstractTextCell extends AbstractCell {
public float getWidthOfText() { public float getWidthOfText() {
assertIsRendered(); assertIsRendered();
final float notBrokenTextWidth = PdfUtil.getStringWidth(getText(), getFont(), getFontSize()); final float notBrokenTextWidth = PdfUtil.getStringWidth(getText(), getFontDescriptor());
if (parameters.isWordBreak()) { if (parameters.isWordBreak()) {
final float maxWidth = getMaxWidthOfText() - getHorizontalPadding(); final float maxWidth = getMaxWidthOfText() - getHorizontalPadding();
List<String> textLines = PdfUtil.getOptimalTextBreakLines(getText(), getFont(), getFontSize(), maxWidth); List<String> textLines = PdfUtil.getOptimalTextBreakLines(getText(), getFontDescriptor(), maxWidth);
return textLines.stream() return textLines.stream()
.map(line -> PdfUtil.getStringWidth(line, getFont(), getFontSize())) .map(line -> PdfUtil.getStringWidth(line, getFontDescriptor()))
.max(Comparator.naturalOrder()) .max(Comparator.naturalOrder())
.orElse(notBrokenTextWidth); .orElse(notBrokenTextWidth);
} }

View file

@ -1,14 +1,12 @@
package org.xbib.graphics.pdfbox.layout.table; package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.element.Paragraph; import org.xbib.graphics.pdfbox.layout.element.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor; import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.text.annotations.AnnotatedStyledText; import org.xbib.graphics.pdfbox.layout.text.annotations.AnnotatedStyledText;
import org.xbib.graphics.pdfbox.layout.text.annotations.Annotations; import org.xbib.graphics.pdfbox.layout.text.annotations.Annotations;
import java.awt.Color; import java.awt.Color;
import java.util.Collections; import java.util.Collections;
import java.util.List;
public class Hyperlink implements ParagraphProcessor { public class Hyperlink implements ParagraphProcessor {
@ -16,24 +14,18 @@ public class Hyperlink implements ParagraphProcessor {
private String url; private String url;
private Font font; private FontDescriptor fontDescriptor;
private Float fontSize;
private Color color = Color.BLUE; private Color color = Color.BLUE;
private float baselineOffset = 1f; private float baselineOffset = 1f;
public void setFontSize(Float fontSize) { public void setFontDescriptor(FontDescriptor fontDescriptor) {
this.fontSize = fontSize; this.fontDescriptor = fontDescriptor;
} }
public void setFont(Font font) { public FontDescriptor getFontDescriptor() {
this.font = font; return fontDescriptor;
}
public Font getFont() {
return font;
} }
public void setText(String text) { public void setText(String text) {
@ -68,16 +60,11 @@ public class Hyperlink implements ParagraphProcessor {
return url; return url;
} }
public Float getFontSize() {
return fontSize;
}
@Override @Override
public void process(Paragraph paragraph, Parameters parameters) { public void process(Paragraph paragraph, Parameters parameters) {
Annotations.HyperlinkAnnotation hyperlink = Annotations.HyperlinkAnnotation hyperlink =
new Annotations.HyperlinkAnnotation(getUrl(), Annotations.HyperlinkAnnotation.LinkStyle.ul); new Annotations.HyperlinkAnnotation(getUrl(), Annotations.HyperlinkAnnotation.LinkStyle.ul);
FontDescriptor fontDescriptor = new FontDescriptor(List.of(getFont() != null ? getFont() : parameters.getFont()), FontDescriptor fontDescriptor = getFontDescriptor() != null ? getFontDescriptor() : parameters.getFontDescriptor();
getFontSize() != null ? getFontSize() : parameters.getFontSize());
paragraph.add(new AnnotatedStyledText(getText(), fontDescriptor, paragraph.add(new AnnotatedStyledText(getText(), fontDescriptor,
getColor(), getBaselineOffset(), 0, 0, Collections.singleton(hyperlink))); getColor(), getBaselineOffset(), 0, 0, Collections.singleton(hyperlink)));
} }

View file

@ -1,17 +1,13 @@
package org.xbib.graphics.pdfbox.layout.table; package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.element.Paragraph; import org.xbib.graphics.pdfbox.layout.element.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.util.List;
public class Markup implements ParagraphProcessor { public class Markup implements ParagraphProcessor {
private String value; private String value;
private Font font; private FontDescriptor fontDescriptor;
private Float fontSize;
public Markup setValue(String value) { public Markup setValue(String value) {
this.value = value; this.value = value;
@ -22,27 +18,17 @@ public class Markup implements ParagraphProcessor {
return value; return value;
} }
public Markup setFont(Font font) { public Markup setFontDescriptor(FontDescriptor fontDescriptor) {
this.font = font; this.fontDescriptor = fontDescriptor;
return this; return this;
} }
public Font getFont() { public FontDescriptor getFontDescriptor() {
return font; return fontDescriptor;
}
public Markup setFontSize(Float fontSize) {
this.fontSize = fontSize;
return this;
}
public Float getFontSize() {
return fontSize;
} }
@Override @Override
public void process(Paragraph paragraph, Parameters parameters) { public void process(Paragraph paragraph, Parameters parameters) {
float fontSize = getFontSize() != null ? getFontSize() : parameters.getFontSize(); paragraph.addMarkup(getValue(), fontDescriptor);
paragraph.addMarkup(getValue(), fontSize, List.of(font));
} }
} }

View file

@ -1,13 +1,14 @@
package org.xbib.graphics.pdfbox.layout.table; package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.awt.Color; import java.awt.Color;
import java.util.List;
public class Parameters { public class Parameters {
private Font font; private FontDescriptor fontDescriptor;
private Float fontSize;
private Color textColor; private Color textColor;
@ -47,6 +48,10 @@ public class Parameters {
// For callers outside it should expose only the primitive though. // For callers outside it should expose only the primitive though.
private Boolean wordBreak; private Boolean wordBreak;
public Parameters() {
setFontDescriptor(new FontDescriptor(List.of(BaseFont.HELVETICA), 11.0f));
}
public boolean isWordBreak() { public boolean isWordBreak() {
return wordBreak != null && wordBreak; return wordBreak != null && wordBreak;
} }
@ -133,12 +138,8 @@ public class Parameters {
return horizontalAlignment; return horizontalAlignment;
} }
public Float getFontSize() { public FontDescriptor getFontDescriptor() {
return fontSize; return fontDescriptor;
}
public Font getFont() {
return font;
} }
public VerticalAlignment getVerticalAlignment() { public VerticalAlignment getVerticalAlignment() {
@ -185,12 +186,8 @@ public class Parameters {
this.borderWidthTop = borderWidthTop; this.borderWidthTop = borderWidthTop;
} }
public void setFont(Font font) { public void setFontDescriptor(FontDescriptor fontDescriptor) {
this.font = font; this.fontDescriptor = fontDescriptor;
}
public void setFontSize(Float fontSize) {
this.fontSize = fontSize;
} }
public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment) { public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment) {
@ -311,11 +308,8 @@ public class Parameters {
} }
private void fillingMergeFontSettings(Parameters parameters) { private void fillingMergeFontSettings(Parameters parameters) {
if (getFont() == null && parameters.getFont() != null) { if (getFontDescriptor() == null && parameters.getFontDescriptor() != null) {
font = parameters.getFont(); setFontDescriptor(parameters.getFontDescriptor());
}
if (getFontSize() == null && parameters.getFontSize() != null) {
fontSize = parameters.getFontSize();
} }
} }
} }

View file

@ -3,7 +3,7 @@ package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.element.Drawable; import org.xbib.graphics.pdfbox.layout.element.Drawable;
import org.xbib.graphics.pdfbox.layout.element.Element; import org.xbib.graphics.pdfbox.layout.element.Element;
import org.xbib.graphics.pdfbox.layout.element.HorizontalRuler; import org.xbib.graphics.pdfbox.layout.element.HorizontalRuler;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.awt.Color; import java.awt.Color;
import java.util.ArrayList; import java.util.ArrayList;
@ -112,13 +112,8 @@ public class Row {
return this; return this;
} }
public Builder font(Font font) { public Builder fontDescriptor(FontDescriptor fontDescriptor) {
parameters.setFont(font); parameters.setFontDescriptor(fontDescriptor);
return this;
}
public Builder fontSize(float fontSize) {
parameters.setFontSize(fontSize);
return this; return this;
} }

View file

@ -1,20 +1,16 @@
package org.xbib.graphics.pdfbox.layout.table; package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.element.Paragraph; import org.xbib.graphics.pdfbox.layout.element.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor; import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.util.PdfUtil; import org.xbib.graphics.pdfbox.layout.util.PdfUtil;
import java.awt.Color; import java.awt.Color;
import java.util.List;
public class StyledText implements ParagraphProcessor { public class StyledText implements ParagraphProcessor {
private String text; private String text;
private Float fontSize; private FontDescriptor fontDescriptor;
private Font font;
private Color color; private Color color;
@ -26,20 +22,12 @@ public class StyledText implements ParagraphProcessor {
return text; return text;
} }
public void setFontSize(Float fontSize) { public void setFontDescriptor(FontDescriptor fontDescriptor) {
this.fontSize = fontSize; this.fontDescriptor = fontDescriptor;
} }
public Float getFontSize() { public FontDescriptor getFontDescriptor() {
return fontSize; return fontDescriptor;
}
public void setFont(Font font) {
this.font = font;
}
public Font getFont() {
return font;
} }
public void setColor(Color color) { public void setColor(Color color) {
@ -52,16 +40,14 @@ public class StyledText implements ParagraphProcessor {
@Override @Override
public void process(Paragraph paragraph, Parameters parameters) { public void process(Paragraph paragraph, Parameters parameters) {
final float actualFontSize = getFontSize() != null ? getFontSize() : parameters.getFontSize(); final FontDescriptor fontDescriptor = getFontDescriptor() != null ? getFontDescriptor() : parameters.getFontDescriptor();
final Font actualFont = getFont() != null ? getFont() : parameters.getFont();
final Color actualColor = getColor() != null ? getColor() : parameters.getTextColor(); final Color actualColor = getColor() != null ? getColor() : parameters.getTextColor();
// TODO this is a complete mess to handle new lines!!!
String[] lines = getText().split(PdfUtil.NEW_LINE_REGEX); String[] lines = getText().split(PdfUtil.NEW_LINE_REGEX);
for (int i = 0; i < lines.length; i++) { for (int i = 0; i < lines.length; i++) {
FontDescriptor fontDescriptor = new FontDescriptor(List.of(actualFont), actualFontSize); paragraph.add(new org.xbib.graphics.pdfbox.layout.text.StyledText(lines[i],
paragraph.add(new org.xbib.graphics.pdfbox.layout.text.StyledText(lines[i], fontDescriptor, actualColor, 0f, 0, 0, 0)); fontDescriptor, actualColor, 0f, 0, 0, 0));
if (i < lines.length - 1) { if (i < lines.length - 1) {
paragraph.add(new org.xbib.graphics.pdfbox.layout.text.NewLine(new FontDescriptor(List.of(actualFont), actualFontSize))); paragraph.add(new org.xbib.graphics.pdfbox.layout.text.NewLine(fontDescriptor));
} }
} }
} }

View file

@ -1,7 +1,7 @@
package org.xbib.graphics.pdfbox.layout.table; package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.font.BaseFont; import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.awt.Color; import java.awt.Color;
import java.awt.Point; import java.awt.Point;
@ -14,9 +14,8 @@ import java.util.Set;
public class Table { public class Table {
private static final Font DEFAULT_FONT = BaseFont.HELVETICA; private static final FontDescriptor DEFAULT_FONT_DESCRIPTOR =
new FontDescriptor(List.of(BaseFont.HELVETICA), 11.0f);
private static final Float DEFAULT_FONT_SIZE = 11f;
private static final Color DEFAULT_TEXT_COLOR = Color.BLACK; private static final Color DEFAULT_TEXT_COLOR = Color.BLACK;
@ -94,10 +93,6 @@ public class Table {
return DEFAULT_HORIZONTAL_ALIGNMENT; return DEFAULT_HORIZONTAL_ALIGNMENT;
} }
public static float getDefaultFontSize() {
return DEFAULT_FONT_SIZE;
}
public int getNumberOfColumns() { public int getNumberOfColumns() {
return numberOfColumns; return numberOfColumns;
} }
@ -110,10 +105,6 @@ public class Table {
return rows; return rows;
} }
public static Font getDefaultFont() {
return DEFAULT_FONT;
}
public Set<Point> getRowSpanCells() { public Set<Point> getRowSpanCells() {
return rowSpanCells; return rowSpanCells;
} }
@ -155,8 +146,7 @@ public class Table {
private float maximumHeight; private float maximumHeight;
private Builder() { private Builder() {
parameters.setFont(DEFAULT_FONT); parameters.setFontDescriptor(DEFAULT_FONT_DESCRIPTOR);
parameters.setFontSize(DEFAULT_FONT_SIZE);
parameters.setTextColor(DEFAULT_TEXT_COLOR); parameters.setTextColor(DEFAULT_TEXT_COLOR);
parameters.setBorderColor(DEFAULT_BORDER_COLOR); parameters.setBorderColor(DEFAULT_BORDER_COLOR);
parameters.setBorderStyleTop(DEFAULT_BORDER_STYLE); parameters.setBorderStyleTop(DEFAULT_BORDER_STYLE);
@ -228,13 +218,8 @@ public class Table {
return this; return this;
} }
public Builder font(Font font) { public Builder fontDescriptor(FontDescriptor fontDescriptor) {
parameters.setFont(font); parameters.setFontDescriptor(fontDescriptor);
return this;
}
public Builder fontSize(Float fontSize) {
parameters.setFontSize(fontSize);
return this; return this;
} }

View file

@ -1,6 +1,6 @@
package org.xbib.graphics.pdfbox.layout.table; package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.table.render.Renderer; import org.xbib.graphics.pdfbox.layout.table.render.Renderer;
import org.xbib.graphics.pdfbox.layout.table.render.TextCellRenderer; import org.xbib.graphics.pdfbox.layout.table.render.TextCellRenderer;
import java.awt.Color; import java.awt.Color;
@ -48,13 +48,8 @@ public class TextCell extends AbstractTextCell {
return this; return this;
} }
public Builder font(Font font) { public Builder fontDescriptor(FontDescriptor fontDescriptor) {
parameters.setFont(font); parameters.setFontDescriptor(fontDescriptor);
return this;
}
public Builder fontSize(Float fontSize) {
parameters.setFontSize(fontSize);
return this; return this;
} }

View file

@ -1,6 +1,6 @@
package org.xbib.graphics.pdfbox.layout.table.render; package org.xbib.graphics.pdfbox.layout.table.render;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.awt.Color; import java.awt.Color;
@ -12,18 +12,15 @@ public class PositionedStyledText {
private final String text; private final String text;
private final Font font; private final FontDescriptor fontDescriptor;
private final float fontSize;
private final Color color; private final Color color;
public PositionedStyledText(float x, float y, String text, Font font, float fontSize, Color color) { public PositionedStyledText(float x, float y, String text, FontDescriptor fontDescriptor, Color color) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.text = text; this.text = text;
this.font = font; this.fontDescriptor = fontDescriptor;
this.fontSize = fontSize;
this.color = color; this.color = color;
} }
@ -39,12 +36,8 @@ public class PositionedStyledText {
return text; return text;
} }
public Font getFont() { public FontDescriptor getFontDescriptor() {
return font; return fontDescriptor;
}
public float getFontSize() {
return fontSize;
} }
public Color getColor() { public Color getColor() {

View file

@ -3,7 +3,7 @@ package org.xbib.graphics.pdfbox.layout.table.render;
import static org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment.CENTER; import static org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment.CENTER;
import static org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment.JUSTIFY; import static org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment.JUSTIFY;
import static org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment.RIGHT; import static org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment.RIGHT;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.table.AbstractTextCell; import org.xbib.graphics.pdfbox.layout.table.AbstractTextCell;
import org.xbib.graphics.pdfbox.layout.util.PdfUtil; import org.xbib.graphics.pdfbox.layout.util.PdfUtil;
import org.xbib.graphics.pdfbox.layout.util.RenderUtil; import org.xbib.graphics.pdfbox.layout.util.RenderUtil;
@ -23,16 +23,15 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
@Override @Override
public void renderContent(TableRenderContext tableRenderContext) { public void renderContent(TableRenderContext tableRenderContext) {
float startX = tableRenderContext.getStartingPoint().x; float startX = tableRenderContext.getStartingPoint().x;
Font currentFont = cell.getFont(); FontDescriptor fontDescriptor = cell.getFontDescriptor();
float currentFontSize = cell.getFontSize();
Color currentTextColor = cell.getTextColor(); Color currentTextColor = cell.getTextColor();
float yOffset = tableRenderContext.getStartingPoint().y + getAdaptionForVerticalAlignment(); float yOffset = tableRenderContext.getStartingPoint().y + getAdaptionForVerticalAlignment();
float xOffset = startX + cell.getPaddingLeft(); float xOffset = startX + cell.getPaddingLeft();
final List<String> lines = calculateAndGetLines(currentFont, currentFontSize, cell.getMaxWidth()); final List<String> lines = calculateAndGetLines(fontDescriptor, cell.getMaxWidth());
for (int i = 0; i < lines.size(); i++) { for (int i = 0; i < lines.size(); i++) {
final String line = lines.get(i); final String line = lines.get(i);
yOffset -= calculateYOffset(currentFont, currentFontSize, i); yOffset -= calculateYOffset(line, fontDescriptor, i);
final float textWidth = PdfUtil.getStringWidth(line, currentFont, currentFontSize); final float textWidth = PdfUtil.getStringWidth(line, fontDescriptor);
if (cell.isHorizontallyAligned(RIGHT)) { if (cell.isHorizontallyAligned(RIGHT)) {
xOffset = startX + (cell.getWidth() - (textWidth + cell.getPaddingRight())); xOffset = startX + (cell.getWidth() - (textWidth + cell.getPaddingRight()));
} else if (cell.isHorizontallyAligned(CENTER)) { } else if (cell.isHorizontallyAligned(CENTER)) {
@ -44,8 +43,8 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
throw new UncheckedIOException(exception); throw new UncheckedIOException(exception);
} }
} }
PositionedStyledText positionedStyledText = new PositionedStyledText(xOffset, yOffset, line, PositionedStyledText positionedStyledText =
currentFont, currentFontSize, currentTextColor); new PositionedStyledText(xOffset, yOffset, line, fontDescriptor, currentTextColor);
RenderUtil.drawText(tableRenderContext.getContentStream(), positionedStyledText); RenderUtil.drawText(tableRenderContext.getContentStream(), positionedStyledText);
} }
} }
@ -55,9 +54,9 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
return cell.getTextHeight(); return cell.getTextHeight();
} }
private float calculateYOffset(Font currentFont, float currentFontSize, int lineIndex) { private float calculateYOffset(String text, FontDescriptor fontDescriptor, int lineIndex) {
return PdfUtil.getFontHeight(currentFont, currentFontSize) + return PdfUtil.getFontHeight(text, fontDescriptor) +
(lineIndex > 0 ? PdfUtil.getFontHeight(currentFont, currentFontSize) * cell.getLineSpacing() : 0f); (lineIndex > 0 ? PdfUtil.getFontHeight(text, fontDescriptor) * cell.getLineSpacing() : 0f);
} }
private static boolean isNotLastLine(List<String> lines, int i) { private static boolean isNotLastLine(List<String> lines, int i) {
@ -67,7 +66,7 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
private float calculateCharSpacingFor(String line) { private float calculateCharSpacingFor(String line) {
float charSpacing = 0; float charSpacing = 0;
if (line.length() > 1) { if (line.length() > 1) {
float size = PdfUtil.getStringWidth(line, cell.getFont(), cell.getFontSize()); float size = PdfUtil.getStringWidth(line, cell.getFontDescriptor());
float free = cell.getWidthOfText() - size; float free = cell.getWidthOfText() - size;
if (free > 0) { if (free > 0) {
charSpacing = free / (line.length() - 1); charSpacing = free / (line.length() - 1);
@ -76,9 +75,9 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
return charSpacing; return charSpacing;
} }
private List<String> calculateAndGetLines(Font currentFont, float currentFontSize, float maxWidth) { private List<String> calculateAndGetLines(FontDescriptor fontDescriptor, float maxWidth) {
return cell.isWordBreak() return cell.isWordBreak()
? PdfUtil.getOptimalTextBreakLines(cell.getText(), currentFont, currentFontSize, maxWidth) ? PdfUtil.getOptimalTextBreakLines(cell.getText(), fontDescriptor, maxWidth)
: Collections.singletonList(cell.getText()); : Collections.singletonList(cell.getText());
} }
} }

View file

@ -3,6 +3,7 @@ package org.xbib.graphics.pdfbox.layout.table.render;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.util.Matrix; import org.apache.pdfbox.util.Matrix;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.util.PdfUtil; import org.xbib.graphics.pdfbox.layout.util.PdfUtil;
import org.xbib.graphics.pdfbox.layout.table.VerticalTextCell; import org.xbib.graphics.pdfbox.layout.table.VerticalTextCell;
@ -27,8 +28,7 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
public void renderContent(TableRenderContext tableRenderContext) { public void renderContent(TableRenderContext tableRenderContext) {
float startX = tableRenderContext.getStartingPoint().x; float startX = tableRenderContext.getStartingPoint().x;
float startY = tableRenderContext.getStartingPoint().y; float startY = tableRenderContext.getStartingPoint().y;
Font currentFont = cell.getFont(); FontDescriptor fontDescriptor = cell.getFontDescriptor();
float currentFontSize = cell.getFontSize();
Color currentTextColor = cell.getTextColor(); Color currentTextColor = cell.getTextColor();
float yOffset = startY + cell.getPaddingBottom(); float yOffset = startY + cell.getPaddingBottom();
float height = cell.getRow().getHeight(); float height = cell.getRow().getHeight();
@ -38,13 +38,13 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
height = cell.calculateHeightForRowSpan(); height = cell.calculateHeightForRowSpan();
} }
final List<String> lines = cell.isWordBreak() final List<String> lines = cell.isWordBreak()
? PdfUtil.getOptimalTextBreakLines(cell.getText(), currentFont, currentFontSize, (height - cell.getVerticalPadding())) ? PdfUtil.getOptimalTextBreakLines(cell.getText(), fontDescriptor, (height - cell.getVerticalPadding()))
: Collections.singletonList(cell.getText()); : Collections.singletonList(cell.getText());
float xOffset = startX + cell.getPaddingLeft() - PdfUtil.getFontHeight(currentFont, currentFontSize); float xOffset = startX + cell.getPaddingLeft(); /* - PdfUtil.getFontHeight(currentFont, currentFontSize)*/;
for (int i = 0; i < lines.size(); i++) { for (int i = 0; i < lines.size(); i++) {
final String line = lines.get(i); final String line = lines.get(i);
xOffset += (PdfUtil.getFontHeight(currentFont, currentFontSize) + (i > 0 ? PdfUtil.getFontHeight(currentFont, currentFontSize) * cell.getLineSpacing() : 0f)); xOffset += (PdfUtil.getFontHeight(line, fontDescriptor) + (i > 0 ? PdfUtil.getFontHeight(line, fontDescriptor) * cell.getLineSpacing() : 0f));
drawText(line, currentFont, currentFontSize, currentTextColor, xOffset, yOffset, tableRenderContext.getContentStream()); drawText(line, fontDescriptor, currentTextColor, xOffset, yOffset, tableRenderContext.getContentStream());
} }
} }
@ -54,22 +54,31 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
return 0; return 0;
} }
protected void drawText(String text, Font font, float fontSize, Color color, float x, float y, PDPageContentStream contentStream) { protected void drawText(String text,
FontDescriptor fontDescriptor,
Color color,
float x,
float y,
PDPageContentStream contentStream) {
try { try {
for (Font font : fontDescriptor.getFonts()) {
if (font.canWrite(text)) {
// Rotate by 90 degrees counter clockwise // Rotate by 90 degrees counter clockwise
AffineTransform transform = AffineTransform.getTranslateInstance(x, y); AffineTransform transform = AffineTransform.getTranslateInstance(x, y);
transform.concatenate(AffineTransform.getRotateInstance(Math.PI * 0.5)); transform.concatenate(AffineTransform.getRotateInstance(Math.PI * 0.5));
transform.concatenate(AffineTransform.getTranslateInstance(-x, -y - fontSize)); transform.concatenate(AffineTransform.getTranslateInstance(-x, -y - fontDescriptor.getSize()));
contentStream.moveTo(x, y); contentStream.moveTo(x, y);
contentStream.beginText(); contentStream.beginText();
contentStream.setTextMatrix(new Matrix(transform)); contentStream.setTextMatrix(new Matrix(transform));
contentStream.setNonStrokingColor(color); contentStream.setNonStrokingColor(color);
// TODO select correct font // TODO select correct font style
contentStream.setFont(font.getRegularFont(), fontSize); contentStream.setFont(font.getRegularFont(), fontDescriptor.getSize());
contentStream.newLineAtOffset(x, y); contentStream.newLineAtOffset(x, y);
contentStream.showText(text); contentStream.showText(text);
contentStream.endText(); contentStream.endText();
contentStream.setCharacterSpacing(0); contentStream.setCharacterSpacing(0);
}
}
} catch (IOException e) { } catch (IOException e) {
throw new UncheckedIOException(e); throw new UncheckedIOException(e);
} }

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.pdfbox.layout.util; package org.xbib.graphics.pdfbox.layout.util;
import org.xbib.graphics.pdfbox.layout.font.Font; import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.table.CouldNotDetermineStringWidthException; import org.xbib.graphics.pdfbox.layout.table.CouldNotDetermineStringWidthException;
import java.io.IOException; import java.io.IOException;
@ -10,7 +11,6 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Stack; import java.util.Stack;
import java.util.stream.Collectors;
/** /**
* Provides some helping functions. * Provides some helping functions.
@ -29,16 +29,15 @@ public final class PdfUtil {
* Computes the width of a String (in points). * Computes the width of a String (in points).
* *
* @param text Text * @param text Text
* @param font Font of Text * @param fontDescriptor Font of Text
* @param fontSize FontSize of String
* @return Width (in points) * @return Width (in points)
*/ */
public static float getStringWidth(String text, Font font, float fontSize) { public static float getStringWidth(String text, FontDescriptor fontDescriptor) {
return Arrays.stream(text.split(NEW_LINE_REGEX)) return Arrays.stream(text.split(NEW_LINE_REGEX))
.max(Comparator.comparing(String::length)) .max(Comparator.comparing(String::length))
.map(x -> { .map(x -> {
try { try {
return getWidthOfStringWithoutNewlines(x, font, fontSize); return getWidthOfStringWithoutNewlines(x, fontDescriptor);
} catch (IOException exception) { } catch (IOException exception) {
return 0f; return 0f;
} }
@ -46,16 +45,25 @@ public final class PdfUtil {
.orElseThrow(CouldNotDetermineStringWidthException::new); .orElseThrow(CouldNotDetermineStringWidthException::new);
} }
private static float getWidthOfStringWithoutNewlines(String text, Font font, float fontSize) throws IOException { private static float getWidthOfStringWithoutNewlines(String text, FontDescriptor fontDescriptor) throws IOException {
List<String> codePointsAsString = text.codePoints() List<String> codePointsAsString = text.codePoints()
.mapToObj(codePoint -> new String(new int[]{codePoint}, 0, 1)) .mapToObj(codePoint -> new String(new int[]{codePoint}, 0, 1))
.collect(Collectors.toList()); .toList();
List<Float> widths = new ArrayList<>(); List<Float> widths = new ArrayList<>();
for (String codepoint : codePointsAsString) { for (String codepoint : codePointsAsString) {
boolean found = false;
for (Font font : fontDescriptor.getFonts()) {
if (font.canWrite(codepoint)) {
try { try {
widths.add(font.getRegularFont().getStringWidth(codepoint) * fontSize / 1000F); widths.add(font.getRegularFont().getStringWidth(codepoint) * fontDescriptor.getSize() / 1000F);
} catch (final IllegalArgumentException | IOException e) { } catch (IllegalArgumentException | IOException e) {
widths.add(font.getRegularFont().getStringWidth("") * fontSize / 1000F); widths.add(font.getRegularFont().getStringWidth("") * fontDescriptor.getSize() / 1000F);
}
found = true;
}
}
if (!found) {
throw new IllegalArgumentException("unable to get width of string " + codepoint);
} }
} }
return widths.stream().reduce(0.0f, Float::sum); return widths.stream().reduce(0.0f, Float::sum);
@ -64,37 +72,40 @@ public final class PdfUtil {
/** /**
* Computes the height of a font. * Computes the height of a font.
* *
* @param font Font * @param fontDescriptor font
* @param fontSize FontSize * @return height of font
* @return Height of font
*/ */
public static float getFontHeight(Font font, float fontSize) { public static float getFontHeight(String text, FontDescriptor fontDescriptor) {
return font.getRegularFont().getFontDescriptor().getCapHeight() * fontSize / 1000F; for (Font font : fontDescriptor.getFonts()) {
if (font.canWrite(text)) {
return font.getRegularFont().getFontDescriptor().getCapHeight() * fontDescriptor.getSize() / 1000F;
}
}
throw new IllegalArgumentException("unable to get font height for text " + text + ", fonts = " + fontDescriptor.getFonts());
} }
/** /**
* Split a text into multiple lines to prevent a text-overflow. * Split a text into multiple lines to prevent a text-overflow.
* *
* @param text Text * @param text Text
* @param font Used font * @param fontDescriptor Used font
* @param fontSize Used fontSize
* @param maxWidth Maximal width of resulting text-lines * @param maxWidth Maximal width of resulting text-lines
* @return A list of lines, where all are smaller than maxWidth * @return A list of lines, where all are smaller than maxWidth
*/ */
public static List<String> getOptimalTextBreakLines(String text, Font font, float fontSize, float maxWidth) { public static List<String> getOptimalTextBreakLines(String text, FontDescriptor fontDescriptor, float maxWidth) {
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
for (String line : text.split(NEW_LINE_REGEX)) { for (String line : text.split(NEW_LINE_REGEX)) {
if (PdfUtil.doesTextLineFit(line, font, fontSize, maxWidth)) { if (doesTextLineFit(line, fontDescriptor, maxWidth)) {
result.add(line); result.add(line);
} else { } else {
result.addAll(PdfUtil.wrapLine(line, font, fontSize, maxWidth)); result.addAll(wrapLine(line, fontDescriptor, maxWidth));
} }
} }
return result; return result;
} }
private static List<String> wrapLine(String line, Font font, float fontSize, float maxWidth) { private static List<String> wrapLine(String line, FontDescriptor fontDescriptor, float maxWidth) {
if (doesTextLineFit(line, font, fontSize, maxWidth)) { if (doesTextLineFit(line, fontDescriptor, maxWidth)) {
return Collections.singletonList(line); return Collections.singletonList(line);
} }
List<String> goodLines = new ArrayList<>(); List<String> goodLines = new ArrayList<>();
@ -102,30 +113,30 @@ public final class PdfUtil {
Arrays.asList(line.split("(?<=[\\\\. ,-])")).forEach(allWords::push); Arrays.asList(line.split("(?<=[\\\\. ,-])")).forEach(allWords::push);
Collections.reverse(allWords); Collections.reverse(allWords);
while (!allWords.empty()) { while (!allWords.empty()) {
goodLines.add(buildALine(allWords, font, fontSize, maxWidth)); goodLines.add(buildALine(allWords, fontDescriptor, maxWidth));
} }
return goodLines; return goodLines;
} }
private static List<String> splitBySize(String line, Font font, float fontSize, float maxWidth) { private static List<String> splitBySize(String line, FontDescriptor fontDescriptor, float maxWidth) {
List<String> returnList = new ArrayList<>(); List<String> returnList = new ArrayList<>();
for (int i = line.length() - 1; i > 0; i--) { for (int i = line.length() - 1; i > 0; i--) {
String fittedNewLine = line.substring(0, i) + "-"; String fittedNewLine = line.substring(0, i) + "-";
String remains = line.substring(i); String remains = line.substring(i);
if (PdfUtil.doesTextLineFit(fittedNewLine, font, fontSize, maxWidth)) { if (PdfUtil.doesTextLineFit(fittedNewLine, fontDescriptor, maxWidth)) {
returnList.add(fittedNewLine); returnList.add(fittedNewLine);
returnList.addAll(PdfUtil.wrapLine(remains, font, fontSize, maxWidth)); returnList.addAll(PdfUtil.wrapLine(remains, fontDescriptor, maxWidth));
break; break;
} }
} }
return returnList; return returnList;
} }
private static String buildALine(Stack<String> words, Font font, float fontSize, float maxWidth) { private static String buildALine(Stack<String> words, FontDescriptor fontDescriptor, float maxWidth) {
StringBuilder line = new StringBuilder(); StringBuilder line = new StringBuilder();
float width = 0; float width = 0;
while (!words.empty()) { while (!words.empty()) {
float nextWordWidth = getStringWidth(words.peek(), font, fontSize); float nextWordWidth = getStringWidth(words.peek(), fontDescriptor);
if (line.length() == 0 && words.peek().length() == 1 && nextWordWidth > maxWidth) { if (line.length() == 0 && words.peek().length() == 1 && nextWordWidth > maxWidth) {
return words.pop(); return words.pop();
} }
@ -137,23 +148,23 @@ public final class PdfUtil {
} }
} }
if (width == 0 && !words.empty()) { if (width == 0 && !words.empty()) {
List<String> cutBySize = splitBySize(words.pop(), font, fontSize, maxWidth); List<String> cutBySize = splitBySize(words.pop(), fontDescriptor, maxWidth);
Collections.reverse(cutBySize); Collections.reverse(cutBySize);
cutBySize.forEach(words::push); cutBySize.forEach(words::push);
return buildALine(words, font, fontSize, maxWidth); return buildALine(words, fontDescriptor, maxWidth);
} }
return line.toString().trim(); return line.toString().trim();
} }
private static boolean doesTextLineFit(String textLine, Font font, float fontSize, float maxWidth) { private static boolean doesTextLineFit(String textLine, FontDescriptor fontDescriptor, float maxWidth) {
return doesTextLineFit(PdfUtil.getStringWidth(textLine, font, fontSize), maxWidth); return doesTextLineFit(getStringWidth(textLine, fontDescriptor), maxWidth);
} }
private static boolean doesTextLineFit(float stringWidth, float maxWidth) { private static boolean doesTextLineFit(float stringWidth, float max) {
if (isEqualInEpsilon(stringWidth, maxWidth)) { if (isEqualInEpsilon(stringWidth, max)) {
return true; return true;
} }
return maxWidth > stringWidth; return max > stringWidth;
} }
private static boolean isEqualInEpsilon(float x, float y) { private static boolean isEqualInEpsilon(float x, float y) {

View file

@ -2,6 +2,7 @@ package org.xbib.graphics.pdfbox.layout.util;
import static org.xbib.graphics.pdfbox.layout.table.BorderStyle.SOLID; import static org.xbib.graphics.pdfbox.layout.table.BorderStyle.SOLID;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.table.render.PositionedLine; import org.xbib.graphics.pdfbox.layout.table.render.PositionedLine;
import org.xbib.graphics.pdfbox.layout.table.render.PositionedRectangle; import org.xbib.graphics.pdfbox.layout.table.render.PositionedRectangle;
import org.xbib.graphics.pdfbox.layout.table.render.PositionedStyledText; import org.xbib.graphics.pdfbox.layout.table.render.PositionedStyledText;
@ -16,11 +17,13 @@ public class RenderUtil {
} }
public static void drawText(PDPageContentStream contentStream, PositionedStyledText styledText) { public static void drawText(PDPageContentStream contentStream, PositionedStyledText styledText) {
for (Font font : styledText.getFontDescriptor().getFonts()) {
if (font.canWrite(styledText.getText())) {
try { try {
contentStream.beginText(); contentStream.beginText();
contentStream.setNonStrokingColor(styledText.getColor()); contentStream.setNonStrokingColor(styledText.getColor());
// TODO select correct font // TODO select correct font style
contentStream.setFont(styledText.getFont().getRegularFont(), styledText.getFontSize()); contentStream.setFont(font.getRegularFont(), styledText.getFontDescriptor().getSize());
contentStream.newLineAtOffset(styledText.getX(), styledText.getY()); contentStream.newLineAtOffset(styledText.getX(), styledText.getY());
contentStream.showText(styledText.getText()); contentStream.showText(styledText.getText());
contentStream.endText(); contentStream.endText();
@ -29,6 +32,8 @@ public class RenderUtil {
throw new UncheckedIOException(e); throw new UncheckedIOException(e);
} }
} }
}
}
public static void drawLine(PDPageContentStream contentStream, PositionedLine line) { public static void drawLine(PDPageContentStream contentStream, PositionedLine line) {
try { try {

View file

@ -12,6 +12,7 @@ import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.font.BaseFont; import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.table.AbstractCell; import org.xbib.graphics.pdfbox.layout.table.AbstractCell;
import org.xbib.graphics.pdfbox.layout.table.BorderStyle; import org.xbib.graphics.pdfbox.layout.table.BorderStyle;
import org.xbib.graphics.pdfbox.layout.table.Column; import org.xbib.graphics.pdfbox.layout.table.Column;
@ -26,6 +27,7 @@ import org.xbib.graphics.pdfbox.layout.table.TextCell;
import java.awt.Color; import java.awt.Color;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List;
public class TableTest { public class TableTest {
@ -104,13 +106,13 @@ public class TableTest {
final Table table = Table.builder() final Table table = Table.builder()
.addColumnOfWidth(12) .addColumnOfWidth(12)
.addColumnOfWidth(34) .addColumnOfWidth(34)
.fontSize(12f) .fontDescriptor(new FontDescriptor(List.of(BaseFont.HELVETICA), 12f))
.addRow(Row.builder() .addRow(Row.builder()
.add(TextCell.builder().text("11").paddingTop(35).paddingBottom(15).build()) .add(TextCell.builder().text("11").paddingTop(35).paddingBottom(15).build())
.add(TextCell.builder().text("12").paddingTop(15).paddingBottom(25).build()) .add(TextCell.builder().text("12").paddingTop(15).paddingBottom(25).build())
.build()) .build())
.build(); .build();
final float actualFontHeight = PdfUtil.getFontHeight(table.getSettings().getFont(), 12); final float actualFontHeight = PdfUtil.getFontHeight("test", table.getSettings().getFontDescriptor());
assertThat(table.getHeight(), equalTo(50 + actualFontHeight)); assertThat(table.getHeight(), equalTo(50 + actualFontHeight));
} }
@ -137,7 +139,7 @@ public class TableTest {
.add(TextCell.builder().text("This text should break because too long").colSpan(2).borderWidth(1).build()) .add(TextCell.builder().text("This text should break because too long").colSpan(2).borderWidth(1).build())
.add(TextCell.builder().text("Booz").build()) .add(TextCell.builder().text("Booz").build())
.wordBreak(true) .wordBreak(true)
.font(BaseFont.COURIER).fontSize(8) .fontDescriptor(new FontDescriptor(List.of(BaseFont.COURIER), 8.0f))
.build(); .build();
row.getHeight(); row.getHeight();
}); });
@ -148,13 +150,12 @@ public class TableTest {
Table.Builder tableBuilder = Table.builder() Table.Builder tableBuilder = Table.builder()
.addColumnsOfWidth(10, 10, 10) .addColumnsOfWidth(10, 10, 10)
.horizontalAlignment(HorizontalAlignment.CENTER) .horizontalAlignment(HorizontalAlignment.CENTER)
.fontSize(10f) .fontDescriptor(new FontDescriptor(List.of(BaseFont.HELVETICA), 10.0f))
.font(BaseFont.HELVETICA)
.wordBreak(false); .wordBreak(false);
Row row = Row.builder() Row row = Row.builder()
.add(TextCell.builder().text("iVgebALheQlBkxtDyNDrhKv").colSpan(2).borderWidth(1).build()) .add(TextCell.builder().text("iVgebALheQlBkxtDyNDrhKv").colSpan(2).borderWidth(1).build())
.add(TextCell.builder().text("Booz").build()) .add(TextCell.builder().text("Booz").build())
.font(BaseFont.COURIER).fontSize(8) .fontDescriptor(new FontDescriptor(List.of(BaseFont.COURIER), 8.0f))
.build(); .build();
tableBuilder.addRow(row); tableBuilder.addRow(row);
tableBuilder.build(); tableBuilder.build();

View file

@ -128,15 +128,21 @@
"elements": [ "elements": [
{ {
"type": "cell", "type": "cell",
"text": "Cell A" "text": "Cell A",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell B" "text": "Cell B",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell C" "text": "Cell C",
"font": "helvetica",
"fontsize": 11
} }
] ]
}, },
@ -145,15 +151,21 @@
"elements": [ "elements": [
{ {
"type": "cell", "type": "cell",
"text": "Cell D" "text": "Cell D",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell E" "text": "Cell E",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell F" "text": "Cell F",
"font": "helvetica",
"fontsize": 11
} }
] ]
} }
@ -168,15 +180,21 @@
"elements": [ "elements": [
{ {
"type": "cell", "type": "cell",
"text": "Cell 1" "text": "Cell 1",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell 2" "text": "Cell 2",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell 3" "text": "Cell 3",
"font": "helvetica",
"fontsize": 11
} }
] ]
}, },
@ -186,18 +204,24 @@
{ {
"type": "cell", "type": "cell",
"text": "Cell 4", "text": "Cell 4",
"font": "helvetica",
"fontsize": 11,
"padding": "5 5 5 5", "padding": "5 5 5 5",
"borderwidth": 0.5 "borderwidth": 0.5
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell 5", "text": "Cell 5",
"font": "helvetica",
"fontsize": 11,
"padding": "5 5 5 5", "padding": "5 5 5 5",
"borderwidth": 0.5 "borderwidth": 0.5
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell 6", "text": "Cell 6",
"font": "helvetica",
"fontsize": 11,
"padding": "5 5 5 5", "padding": "5 5 5 5",
"borderwidth": 0.5 "borderwidth": 0.5
} }

View file

@ -3,8 +3,7 @@
"margin": "0 0 0 0", "margin": "0 0 0 0",
"author": "Jörg Prante", "author": "Jörg Prante",
"font": [ "font": [
"helvetica", "helvetica"
"notosans"
], ],
"elements": [ "elements": [
{ {
@ -17,15 +16,21 @@
"elements": [ "elements": [
{ {
"type": "cell", "type": "cell",
"text": "Cell A" "text": "Cell A",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell B" "text": "Cell B",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell C" "text": "Cell C",
"font": "helvetica",
"fontsize": 11
} }
] ]
}, },
@ -34,15 +39,21 @@
"elements": [ "elements": [
{ {
"type": "cell", "type": "cell",
"text": "Cell D" "text": "Cell D",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell E" "text": "Cell E",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell F" "text": "Cell F",
"font": "helvetica",
"fontsize": 11
} }
] ]
} }
@ -59,15 +70,21 @@
{ {
"type": "cell", "type": "cell",
"text": "This is very long text for cell 1 This is very long text for cell 1 This is very long text for cell 1", "text": "This is very long text for cell 1 This is very long text for cell 1 This is very long text for cell 1",
"linespacing": 0.5 "linespacing": 0.5,
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell 2" "text": "Cell 2",
"font": "helvetica",
"fontsize": 11
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell 3" "text": "Cell 3",
"font": "helvetica",
"fontsize": 11
} }
] ]
}, },
@ -77,18 +94,24 @@
{ {
"type": "cell", "type": "cell",
"text": "Cell 4", "text": "Cell 4",
"font": "helvetica",
"fontsize": 11,
"padding": "5 5 5 5", "padding": "5 5 5 5",
"borderwidth": 0.5 "borderwidth": 0.5
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell 5", "text": "Cell 5",
"font": "helvetica",
"fontsize": 11,
"padding": "5 5 5 5", "padding": "5 5 5 5",
"borderwidth": 0.5 "borderwidth": 0.5
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell 6", "text": "Cell 6",
"font": "helvetica",
"fontsize": 11,
"padding": "5 5 5 5", "padding": "5 5 5 5",
"borderwidth": 0.5 "borderwidth": 0.5
} }
@ -100,18 +123,24 @@
{ {
"type": "cell", "type": "cell",
"text": "Cell 7", "text": "Cell 7",
"font": "helvetica",
"fontsize": 11,
"padding": "5 5 5 5", "padding": "5 5 5 5",
"borderwidth": 0.5 "borderwidth": 0.5
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell 8", "text": "Cell 8",
"font": "helvetica",
"fontsize": 11,
"padding": "5 5 5 5", "padding": "5 5 5 5",
"borderwidth": 0.5 "borderwidth": 0.5
}, },
{ {
"type": "cell", "type": "cell",
"text": "Cell 9", "text": "Cell 9",
"font": "helvetica",
"fontsize": 11,
"padding": "5 5 5 5", "padding": "5 5 5 5",
"borderwidth": 0.5 "borderwidth": 0.5
} }