From 53a27c5792bce7fb35f211a33301dcb433a91518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Prante?= Date: Fri, 4 Aug 2023 11:26:48 +0200 Subject: [PATCH] switch to multi font parameter, this allows for fallback fonts --- gradle/test/junit5.gradle | 2 +- .../pdfbox/layout/element/Document.java | 124 +++++++++++++++++- .../pdfbox/layout/element/Paragraph.java | 4 +- .../pdfbox/layout/element/TextElement.java | 21 +-- .../scripting/command/CellCommand.java | 9 +- .../scripting/command/DocumentCommand.java | 18 +++ .../scripting/command/MarkupCommand.java | 11 +- .../element/scripting/command/RowCommand.java | 3 +- .../scripting/command/TextCommand.java | 11 +- .../graphics/pdfbox/layout/font/BaseFont.java | 13 +- .../graphics/pdfbox/layout/font/Font.java | 2 + .../pdfbox/layout/font/FontDescriptor.java | 42 +++--- .../graphics/pdfbox/layout/font/Fonts.java | 29 ---- .../pdfbox/layout/font/NotoSansCJKFont.java | 93 ------------- .../pdfbox/layout/font/NotoSansFont.java | 84 ------------ .../pdfbox/layout/font/OpenSansFont.java | 85 ------------ .../pdfbox/layout/font/SourceSansFont.java | 85 ------------ .../pdfbox/layout/table/Hyperlink.java | 3 +- .../graphics/pdfbox/layout/table/Markup.java | 4 +- .../graphics/pdfbox/layout/table/NewLine.java | 4 +- .../pdfbox/layout/table/StyledText.java | 5 +- .../graphics/pdfbox/layout/text/Indent.java | 17 +-- .../pdfbox/layout/text/SpaceUnit.java | 5 +- .../pdfbox/layout/text/StyledText.java | 4 +- .../graphics/pdfbox/layout/text/TextFlow.java | 18 +-- .../pdfbox/layout/text/TextFlowUtil.java | 10 +- .../graphics/pdfbox/layout/text/TextLine.java | 11 +- .../pdfbox/layout/text/TextSequenceUtil.java | 4 +- .../UnderlineAnnotationProcessor.java | 5 +- .../pdfbox/layout/test/AlignedTest.java | 9 +- .../pdfbox/layout/test/ColumnsTest.java | 9 +- .../layout/test/CustomAnnotationTest.java | 8 +- .../layout/test/CustomRendererTest.java | 9 +- .../pdfbox/layout/test/FramesTest.java | 17 +-- .../pdfbox/layout/test/HelloBarcodeTest.java | 3 +- .../pdfbox/layout/test/HelloCatTest.java | 3 +- .../pdfbox/layout/test/HelloDocTest.java | 3 +- .../layout/test/HelloNotoSansCJKFontTest.java | 9 +- .../layout/test/HelloNotoSansFontTest.java | 8 +- .../layout/test/HelloOpenSansFontTest.java | 8 +- .../layout/test/HelloSourceSansFontTest.java | 8 +- .../pdfbox/layout/test/IndentationTest.java | 93 ++++++------- .../pdfbox/layout/test/LandscapeTest.java | 13 +- .../pdfbox/layout/test/LetterTest.java | 12 +- .../pdfbox/layout/test/LineSpacingTest.java | 5 +- .../pdfbox/layout/test/LinksTest.java | 15 ++- .../pdfbox/layout/test/ListenerTest.java | 9 +- .../pdfbox/layout/test/LowLevelText.java | 11 +- .../pdfbox/layout/test/MarginTest.java | 7 +- .../pdfbox/layout/test/MarkupTest.java | 19 +-- .../pdfbox/layout/test/MultiplePagesTest.java | 7 +- .../layout/test/PageFormatRotationTest.java | 11 +- .../graphics/pdfbox/layout/test/Section.java | 4 +- .../pdfbox/layout/test/TextRotationTest.java | 6 +- .../pdfbox/layout/test/scripting.json | 4 + 55 files changed, 426 insertions(+), 610 deletions(-) delete mode 100644 graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/Fonts.java delete mode 100644 graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/NotoSansCJKFont.java delete mode 100644 graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/NotoSansFont.java delete mode 100644 graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/OpenSansFont.java delete mode 100644 graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/SourceSansFont.java diff --git a/gradle/test/junit5.gradle b/gradle/test/junit5.gradle index 9d3ff2b..f503f19 100644 --- a/gradle/test/junit5.gradle +++ b/gradle/test/junit5.gradle @@ -7,7 +7,7 @@ dependencies { test { useJUnitPlatform() - failFast = true + failFast = false environment 'TMPDIR', '/var/tmp/gs' file('/var/tmp/gs').mkdirs() systemProperty 'java.awt.headless', 'true' diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/Document.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/Document.java index b985961..beef5a4 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/Document.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/Document.java @@ -1,7 +1,13 @@ package org.xbib.graphics.pdfbox.layout.element; +import org.apache.fontbox.ttf.TTFParser; +import org.apache.fontbox.ttf.TrueTypeFont; +import org.apache.pdfbox.io.RandomAccessRead; +import org.apache.pdfbox.io.RandomAccessReadBuffer; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentInformation; +import org.apache.pdfbox.pdmodel.font.PDFont; +import org.apache.pdfbox.pdmodel.font.PDType0Font; import org.xbib.graphics.pdfbox.layout.element.render.Layout; import org.xbib.graphics.pdfbox.layout.element.render.LayoutHint; import org.xbib.graphics.pdfbox.layout.element.render.RenderContext; @@ -9,8 +15,12 @@ import org.xbib.graphics.pdfbox.layout.element.render.RenderListener; import org.xbib.graphics.pdfbox.layout.element.render.Renderer; import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayout; import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayoutHint; +import org.xbib.graphics.pdfbox.layout.font.BaseFont; +import org.xbib.graphics.pdfbox.layout.font.Font; + import java.io.Closeable; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.time.Instant; import java.time.ZoneId; @@ -19,6 +29,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -28,11 +39,13 @@ import java.util.Map.Entry; */ public class Document implements Element, Closeable, RenderListener { - private final List> elements = new ArrayList<>(); + private final List> elements; - private final List customRenderer = new ArrayList<>(); + private final Map fonts; - private final List renderListener = new ArrayList<>(); + private final List customRenderer; + + private final List renderListener; private PageFormat pageFormat; @@ -72,7 +85,12 @@ public class Document implements Element, Closeable, RenderListener { public Document(PageFormat pageFormat) { this.pdDocument = new PDDocument(); this.pdDocumentInformation = new PDDocumentInformation(); + this.elements = new ArrayList<>(); + this.fonts = new LinkedHashMap<>(); + this.customRenderer = new ArrayList<>(); + this.renderListener = new ArrayList<>(); setPageFormat(pageFormat); + registerFont("helvetica", BaseFont.HELVETICA); } public void setPageFormat(PageFormat pageFormat) { @@ -127,6 +145,105 @@ public class Document implements Element, Closeable, RenderListener { pdDocumentInformation.setCustomMetadataValue(key, value); } + public void registerFont(String name, Font font) { + fonts.put(name, font); + } + + public void registerNotoSansFont() throws IOException { + registerFont("notosans", + "NotoSans-Regular.ttf", + "NotoSans-Bold.ttf", + "NotoSans-Italic.ttf", + "NotoSans-BoldItalic.ttf"); + } + + public void registerNotoSansCJKSCFont() throws IOException { + registerFont("notosanscjksc", + "NotoSansCJKsc-Regular.ttf", + "NotoSansCJKsc-Bold.ttf", + "NotoSansCJKsc-Italic.ttf", + "NotoSansCJKsc-BoldItalic.ttf"); + } + + public void registerOpenSansFont() throws IOException { + registerFont("opensans", + "OpenSans-Regular.ttf", + "OpenSans-Bold.ttf", + "OpenSans-Italic.ttf", + "OpenSans-BoldItalic.ttf"); + } + + public void registerSourceSansFont() throws IOException { + registerFont("sourcesans", + "SourceSans3-Regular.ttf", + "SourceSans3-Bold.ttf", + "SourceSans3-It.ttf", + "SourceSans3-BoldIt.ttf"); + } + + public void registerFont(String name, + String regularFontResource, + String boldFontResource, + String italicsFontResource, + String boldItalicsFontResource) throws IOException { + final PDType0Font regularFont = loadTrueTypeFont(regularFontResource); + final PDType0Font boldFont = loadTrueTypeFont(boldFontResource); + final PDType0Font italicsFont = loadTrueTypeFont(italicsFontResource); + final PDType0Font boldItalicsFont = loadTrueTypeFont(boldItalicsFontResource); + fonts.put(name, new Font() { + @Override + public PDFont getRegularFont() { + return regularFont; + } + + @Override + public PDFont getBoldFont() { + return boldFont; + } + + @Override + public PDFont getItalicFont() { + return italicsFont; + } + + @Override + public PDFont getBoldItalicFont() { + return boldItalicsFont; + } + + @Override + public boolean hasGlyph(int code) { + try { + return regularFont.hasGlyph(code); + } catch (IOException e) { + return false; + } + } + + @Override + public boolean canWrite(String string) { + try { + return regularFont.getStringWidth(string) > 0; + } catch (IOException e) { + return false; + } + } + }); + } + + private PDType0Font loadTrueTypeFont(String resourceName) throws IOException { + InputStream inputStream = Font.class.getResourceAsStream(resourceName); + TTFParser ttfParser = new TTFParser(); + RandomAccessRead randomAccessRead = new RandomAccessReadBuffer(inputStream); + TrueTypeFont openTypeFont = ttfParser.parse(randomAccessRead); + return PDType0Font.load(pdDocument, openTypeFont, true); + } + + + public Font getFont(String name) { + return fonts.get(name); + } + /** * Adds an element to the document using a {@link VerticalLayoutHint}. * @@ -144,6 +261,7 @@ public class Document implements Element, Closeable, RenderListener { * @param element the element to add * @param layoutHint the hint for the {@link Layout}. */ + @Override public Element add(Element element, LayoutHint layoutHint) { elements.add(Map.entry(element, layoutHint)); return this; diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/Paragraph.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/Paragraph.java index 356dcb7..8e541f8 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/Paragraph.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/Paragraph.java @@ -85,9 +85,9 @@ public class Paragraph extends TextFlow implements Drawable, Element, WidthRespe public Element add(Element element) { if (element instanceof TextElement textElement) { if (textElement.isMarkup()) { - addMarkup(textElement.getValue(), textElement.getFontSize(), textElement.getFont()); + addMarkup(textElement.getValue(), textElement.getFontSize(), textElement.getFonts()); } else { - addText(textElement.getValue(), textElement.getFontSize(), textElement.getFont()); + addText(textElement.getValue(), textElement.getFontSize(), textElement.getFonts()); } } else { throw new UnsupportedOperationException(); diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/TextElement.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/TextElement.java index 5f2766e..a2e1b80 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/TextElement.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/TextElement.java @@ -2,6 +2,8 @@ package org.xbib.graphics.pdfbox.layout.element; import org.xbib.graphics.pdfbox.layout.font.Font; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; public class TextElement implements Element { @@ -10,17 +12,20 @@ public class TextElement implements Element { private final String value; - private final Font font; + private final List fonts; - private final float fontsize; + private float fontsize; - public TextElement(boolean markup, String value, Font font, float fontsize) { + public TextElement(boolean markup, String value) { this.markup = markup; this.value = value; - this.font = font; - this.fontsize = fontsize; Objects.requireNonNull(value, "you must specify a value"); - Objects.requireNonNull(font, "you must specify a font"); + this.fonts = new ArrayList<>(); + } + + public void addFont(Font font, float size) { + this.fonts.add(font); + this.fontsize = size; } public String getValue() { @@ -31,8 +36,8 @@ public class TextElement implements Element { return markup; } - public Font getFont() { - return font; + public List getFonts() { + return fonts; } public float getFontSize() { diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/CellCommand.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/CellCommand.java index 95cf316..c1941c3 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/CellCommand.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/CellCommand.java @@ -4,7 +4,6 @@ import org.xbib.graphics.pdfbox.layout.color.ColorFactory; import org.xbib.graphics.pdfbox.layout.element.Document; import org.xbib.graphics.pdfbox.layout.element.Paragraph; import org.xbib.graphics.pdfbox.layout.font.Font; -import org.xbib.graphics.pdfbox.layout.font.Fonts; import org.xbib.graphics.pdfbox.layout.element.scripting.Engine; import org.xbib.graphics.pdfbox.layout.element.scripting.State; import org.xbib.graphics.pdfbox.layout.table.BorderStyle; @@ -42,7 +41,7 @@ public class CellCommand implements Command { cell.text(settings.get("value")); cell.fontSize(settings.getAsFloat("fontsize", 11.0f)); Document document = state.getDocument(); - Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document); + Font font = document.getFont(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)); cell.font(font); Color color = ColorFactory.web(settings.get("color", "black")); cell.textColor(color); @@ -83,11 +82,11 @@ 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); + float lineSpacing = settings.getAsFloat("linespacing", -1f); Document document = state.getDocument(); - Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document); + Font font = document.getFont(settings.get("font", "helvetica")); cell.add(new Markup().setValue(value).setFont(font).setFontSize(size)); - if (lineSpacing != null && lineSpacing >= 0f) { + if (lineSpacing >= 0f) { cell.lineSpacing(lineSpacing); } state.getElements().peek().add(cell.build()); diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/DocumentCommand.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/DocumentCommand.java index d3391e6..aa1f46e 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/DocumentCommand.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/DocumentCommand.java @@ -4,6 +4,7 @@ import org.xbib.graphics.pdfbox.layout.element.Document; import org.xbib.graphics.pdfbox.layout.element.PageFormat; import org.xbib.graphics.pdfbox.layout.element.scripting.Engine; import org.xbib.graphics.pdfbox.layout.element.scripting.State; +import org.xbib.graphics.pdfbox.layout.font.BaseFont; import org.xbib.settings.Settings; import java.io.IOException; @@ -14,6 +15,9 @@ import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt; public class DocumentCommand implements Command { + public DocumentCommand() { + } + @Override public void execute(Engine engine, State state, Settings settings) throws IOException { PageFormat.PageFormatBuilder pageFormat = PageFormat.builder(); @@ -67,6 +71,20 @@ public class DocumentCommand implements Command { } else { document.setModificationDate(instant); } + if (settings.containsSetting("font")) { + String[] fonts = settings.getAsArray("font"); + for (String font : fonts) { + switch (font) { + case "helvetica" -> document.registerFont("helvetica", BaseFont.HELVETICA); + case "times" -> document.registerFont("times", BaseFont.TIMES); + case "courier" -> document.registerFont("courier", BaseFont.COURIER); + case "notosans" -> document.registerNotoSansFont(); + case "notosanscjksc" -> document.registerNotoSansCJKSCFont(); + case "opensans" -> document.registerOpenSansFont(); + case "sourcesans" -> document.registerSourceSansFont(); + } + } + } state.getElements().push(document); engine.executeElements(settings); } diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/MarkupCommand.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/MarkupCommand.java index fd9baef..750a865 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/MarkupCommand.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/MarkupCommand.java @@ -7,8 +7,6 @@ import org.xbib.graphics.pdfbox.layout.element.TextElement; import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayoutHint; import org.xbib.graphics.pdfbox.layout.element.scripting.Engine; import org.xbib.graphics.pdfbox.layout.element.scripting.State; -import org.xbib.graphics.pdfbox.layout.font.Font; -import org.xbib.graphics.pdfbox.layout.font.Fonts; import org.xbib.graphics.pdfbox.layout.position.Position; import org.xbib.graphics.pdfbox.layout.text.Alignment; import org.xbib.settings.Settings; @@ -22,11 +20,14 @@ public class MarkupCommand implements Command { @Override public void execute(Engine engine, State state, Settings settings) { String value = settings.get("value"); - float fontsize = settings.getAsFloat("fontsize", 11.0f); Document document = state.getDocument(); - Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document); + TextElement textElement = new TextElement(true, value); + String[] fonts = settings.getAsArray("font"); + float fontsize = settings.getAsFloat("fontsize", 10.0f); + for (String font : fonts) { + textElement.addFont(document.getFont(font), fontsize); + } Element element = state.getElements().peek(); - TextElement textElement = new TextElement(true, value, font, fontsize); if (element instanceof Paragraph) { element.add(textElement); } else if (element instanceof Document) { diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/RowCommand.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/RowCommand.java index db1d695..0e9991d 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/RowCommand.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/RowCommand.java @@ -2,7 +2,6 @@ package org.xbib.graphics.pdfbox.layout.element.scripting.command; import org.xbib.graphics.pdfbox.layout.color.ColorFactory; import org.xbib.graphics.pdfbox.layout.element.Document; -import org.xbib.graphics.pdfbox.layout.font.Fonts; import org.xbib.graphics.pdfbox.layout.element.scripting.Engine; import org.xbib.graphics.pdfbox.layout.element.scripting.State; import org.xbib.graphics.pdfbox.layout.table.BorderStyle; @@ -32,7 +31,7 @@ public class RowCommand implements Command { } row.fontSize(settings.getAsFloat("fontsize", 11.0f)); Document document = state.getDocument(); - row.font(Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document)); + row.font(document.getFont(settings.get("font", "helvetica"))); Color color = ColorFactory.web(settings.get("color", "black")); row.textColor(color); if (settings.containsSetting("backgroundcolor")) { diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/TextCommand.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/TextCommand.java index 7fd3c61..94da52c 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/TextCommand.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/element/scripting/command/TextCommand.java @@ -5,8 +5,6 @@ import org.xbib.graphics.pdfbox.layout.element.Element; import org.xbib.graphics.pdfbox.layout.element.Paragraph; import org.xbib.graphics.pdfbox.layout.element.TextElement; import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayoutHint; -import org.xbib.graphics.pdfbox.layout.font.Font; -import org.xbib.graphics.pdfbox.layout.font.Fonts; import org.xbib.graphics.pdfbox.layout.element.scripting.Engine; import org.xbib.graphics.pdfbox.layout.element.scripting.State; import org.xbib.graphics.pdfbox.layout.text.Alignment; @@ -22,11 +20,14 @@ public class TextCommand implements Command { @Override public void execute(Engine engine, State state, Settings settings) { String value = settings.get("value"); - float fontsize = settings.getAsFloat("fontsize", 11.0f); Document document = state.getDocument(); - Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document); + TextElement textElement = new TextElement(false, value); + String[] fonts = settings.getAsArray("font"); + float fontsize = settings.getAsFloat("fontsize", 10.0f); + for (String font : fonts) { + textElement.addFont(document.getFont(font), fontsize); + } Element element = state.getElements().peek(); - TextElement textElement = new TextElement(false, value, font, fontsize); if (element instanceof Paragraph) { element.add(textElement); } else if (element instanceof Document) { diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/BaseFont.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/BaseFont.java index e05775f..30fb4b1 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/BaseFont.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/BaseFont.java @@ -5,6 +5,8 @@ import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.font.Standard14Fonts; import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_BOLD; import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_BOLD_OBLIQUE; @@ -79,9 +81,16 @@ public enum BaseFont implements Font { @Override public boolean canWrite(String string) { + if (string == null) { + return false; + } + String printable = string.replaceAll("\\P{Print}|\\p{Cntrl}|\\p{Space}", ""); + if (printable.isEmpty()) { + return true; + } try { - return regularFont.getStringWidth(string) > 0; - } catch (IOException e) { + return regularFont.getStringWidth(printable) > 0; + } catch (IllegalArgumentException | IOException e) { return false; } } diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/Font.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/Font.java index 3142d69..0a4f122 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/Font.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/Font.java @@ -2,6 +2,8 @@ package org.xbib.graphics.pdfbox.layout.font; import org.apache.pdfbox.pdmodel.font.PDFont; +import java.io.IOException; + public interface Font { PDFont getRegularFont(); diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/FontDescriptor.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/FontDescriptor.java index d643bc4..f1fa5aa 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/FontDescriptor.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/FontDescriptor.java @@ -1,6 +1,8 @@ package org.xbib.graphics.pdfbox.layout.font; import org.apache.pdfbox.pdmodel.font.PDFont; + +import java.util.List; import java.util.Objects; /** @@ -8,7 +10,7 @@ import java.util.Objects; */ public class FontDescriptor { - private final Font font; + private final List fonts; private float size; @@ -18,20 +20,20 @@ public class FontDescriptor { private boolean italic; - public FontDescriptor(Font font, float size) { - this(font, size, false, false); + public FontDescriptor(List fonts, float size) { + this(fonts, size, false, false); } - public FontDescriptor(Font font, float size, boolean bold, boolean italic) { - this.font = font; + public FontDescriptor(List fonts, float size, boolean bold, boolean italic) { + this.fonts = fonts; this.size = size; this.bold = bold; this.italic = italic; this.regular = !bold && !italic; } - public Font getFont() { - return font; + public List getFonts() { + return fonts; } public void setSize(float size) { @@ -52,27 +54,31 @@ public class FontDescriptor { this.regular = !bold && !italic; } - public PDFont getSelectedFont() { - if (regular) { - return font.getRegularFont(); - } - if (italic) { - return bold ? font.getBoldItalicFont() : font.getItalicFont(); - } - if (bold) { - return font.getBoldFont(); + public PDFont getSelectedFont(String text) { + for (Font font : fonts) { + if (font.canWrite(text)) { + if (regular) { + return font.getRegularFont(); + } + if (italic) { + return bold ? font.getBoldItalicFont() : font.getItalicFont(); + } + if (bold) { + return font.getBoldFont(); + } + } } throw new IllegalStateException(); } @Override public String toString() { - return "FontDescriptor [font=" + font + ", size=" + size + "]"; + return "FontDescriptor [font=" + fonts + ", size=" + size + "]"; } @Override public int hashCode() { - return Objects.hash(font, size, regular, bold, italic); + return Objects.hash(fonts, size, regular, bold, italic); } @Override diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/Fonts.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/Fonts.java deleted file mode 100644 index fd9e822..0000000 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/Fonts.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.xbib.graphics.pdfbox.layout.font; - -import org.xbib.graphics.pdfbox.layout.element.Document; - -public enum Fonts { - HELVETICA, - TIMES, - COURIER, - NOTOSANS, - NOTOSANSCJK, - OPENSANS, - SOURCESANS; - - public Font getFont(Document document) { - if ("notosans".equalsIgnoreCase(name())) { - return new NotoSansFont(document); - } - if ("notosanscjk".equalsIgnoreCase(name())) { - return new NotoSansCJKFont(document); - } - if ("opensans".equalsIgnoreCase(name())) { - return new OpenSansFont(document); - } - if ("sourcesans".equalsIgnoreCase(name())) { - return new SourceSansFont(document); - } - return BaseFont.valueOf(name()); - } -} diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/NotoSansCJKFont.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/NotoSansCJKFont.java deleted file mode 100644 index b682050..0000000 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/NotoSansCJKFont.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.xbib.graphics.pdfbox.layout.font; - -import org.apache.fontbox.ttf.TTFParser; -import org.apache.fontbox.ttf.TrueTypeFont; -import org.apache.pdfbox.io.RandomAccessRead; -import org.apache.pdfbox.io.RandomAccessReadBuffer; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDType0Font; -import org.xbib.graphics.pdfbox.layout.element.Document; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; - -public class NotoSansCJKFont implements Font { - - private final PDDocument pdDocument; - - private PDType0Font regularFont; - - private PDType0Font boldFont; - - private PDType0Font italicFont; - - private PDType0Font boldItalicFont; - - public NotoSansCJKFont(Document document) { - this.pdDocument = document.getPdDocument(); - } - - @Override - public PDFont getRegularFont() { - if (regularFont == null) { - regularFont = load("NotoSansCJKsc-Regular.ttf"); - } - return regularFont; - } - - @Override - public PDFont getBoldFont() { - if (boldFont == null) { - boldFont = load("NotoSansCJKsc-Regular.ttf"); - } - return boldFont; - } - - @Override - public PDFont getItalicFont() { - if (italicFont == null) { - italicFont = load("NotoSansCJKsc-Regular.ttf"); - } - return italicFont; - } - - @Override - public PDFont getBoldItalicFont() { - if (boldItalicFont == null) { - boldItalicFont = load("NotoSansCJKsc-Regular.ttf"); - } - return boldItalicFont; - } - - @Override - public boolean hasGlyph(int code) { - try { - return regularFont.hasGlyph(code); - } catch (IOException e) { - return false; - } - } - - @Override - public boolean canWrite(String string) { - try { - return regularFont.getStringWidth(string) > 0; - } catch (IOException e) { - return false; - } - } - - private PDType0Font load(String resourceName) { - try { - InputStream inputStream = NotoSansCJKFont.class.getResourceAsStream(resourceName); - TTFParser ttfParser = new TTFParser(); - RandomAccessRead randomAccessRead = new RandomAccessReadBuffer(inputStream); - TrueTypeFont openTypeFont = ttfParser.parse(randomAccessRead); - return PDType0Font.load(pdDocument, openTypeFont, true); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } -} diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/NotoSansFont.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/NotoSansFont.java deleted file mode 100644 index bde422c..0000000 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/NotoSansFont.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.xbib.graphics.pdfbox.layout.font; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDType0Font; -import org.xbib.graphics.pdfbox.layout.element.Document; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Objects; - -public class NotoSansFont implements Font { - - private final PDDocument pdDocument; - - private PDType0Font regularFont; - - private PDType0Font boldFont; - - private PDType0Font italicFont; - - private PDType0Font boldItalicFont; - - public NotoSansFont(Document document) { - this.pdDocument = document.getPdDocument(); - } - - @Override - public PDFont getRegularFont() { - if (regularFont == null) { - regularFont = load("NotoSans-Regular.ttf"); - } - return regularFont; - } - - @Override - public PDFont getBoldFont() { - if (boldFont == null) { - boldFont = load("NotoSans-Bold.ttf"); - } - return boldFont; - } - - @Override - public PDFont getItalicFont() { - if (italicFont == null) { - italicFont = load("NotoSans-Italic.ttf"); - } - return italicFont; - } - - @Override - public PDFont getBoldItalicFont() { - if (boldItalicFont == null) { - boldItalicFont = load("NotoSans-BoldItalic.ttf"); - } - return boldItalicFont; - } - - @Override - public boolean hasGlyph(int code) { - try { - return regularFont.hasGlyph(code); - } catch (IOException e) { - return false; - } - } - - @Override - public boolean canWrite(String string) { - try { - return regularFont.getStringWidth(string) > 0; - } catch (IOException e) { - return false; - } - } - - private PDType0Font load(String resourceName) { - try { - return PDType0Font.load(pdDocument, Objects.requireNonNull(NotoSansFont.class.getResourceAsStream(resourceName)), true); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } -} diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/OpenSansFont.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/OpenSansFont.java deleted file mode 100644 index bd9effb..0000000 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/OpenSansFont.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.xbib.graphics.pdfbox.layout.font; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDType0Font; -import org.xbib.graphics.pdfbox.layout.element.Document; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Objects; - -public class OpenSansFont implements Font { - - private final PDDocument pdDocument; - - private PDType0Font regularFont; - - private PDType0Font boldFont; - - private PDType0Font italicFont; - - private PDType0Font boldItalicFont; - - public OpenSansFont(Document document) { - this.pdDocument = document.getPdDocument(); - } - - @Override - public PDFont getRegularFont() { - if (regularFont == null) { - regularFont = load("OpenSans-Regular.ttf"); - } - return regularFont; - } - - @Override - public PDFont getBoldFont() { - if (boldFont == null) { - boldFont = load("OpenSans-Bold.ttf"); - } - return boldFont; - } - - @Override - public PDFont getItalicFont() { - if (italicFont == null) { - italicFont = load("OpenSans-Italic.ttf"); - } - return italicFont; - } - - @Override - public PDFont getBoldItalicFont() { - if (boldItalicFont == null) { - boldItalicFont = load("OpenSans-BoldItalic.ttf"); - } - return boldItalicFont; - } - - @Override - public boolean hasGlyph(int code) { - try { - return regularFont.hasGlyph(code); - } catch (IOException e) { - return false; - } - } - - @Override - public boolean canWrite(String string) { - try { - return regularFont.getStringWidth(string) > 0; - } catch (IOException e) { - return false; - } - } - - private PDType0Font load(String resourceName) { - try { - return PDType0Font.load(pdDocument, Objects.requireNonNull(OpenSansFont.class.getResourceAsStream(resourceName)), true); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } -} diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/SourceSansFont.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/SourceSansFont.java deleted file mode 100644 index 8ae2585..0000000 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/font/SourceSansFont.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.xbib.graphics.pdfbox.layout.font; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDType0Font; -import org.xbib.graphics.pdfbox.layout.element.Document; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Objects; - -public class SourceSansFont implements Font { - - private final PDDocument pdDocument; - - private PDType0Font regularFont; - - private PDType0Font boldFont; - - private PDType0Font italicFont; - - private PDType0Font boldItalicFont; - - public SourceSansFont(Document document) { - this.pdDocument = document.getPdDocument(); - } - - @Override - public PDFont getRegularFont() { - if (regularFont == null) { - regularFont = load("SourceSans3-Regular.ttf"); - } - return regularFont; - } - - @Override - public PDFont getBoldFont() { - if (boldFont == null) { - boldFont = load("SourceSans3-Bold.ttf"); - } - return boldFont; - } - - @Override - public PDFont getItalicFont() { - if (italicFont == null) { - italicFont = load("SourceSans3-It.ttf"); - } - return italicFont; - } - - @Override - public PDFont getBoldItalicFont() { - if (boldItalicFont == null) { - boldItalicFont = load("SourceSans3-BoldIt.ttf"); - } - return boldItalicFont; - } - - @Override - public boolean hasGlyph(int code) { - try { - return regularFont.hasGlyph(code); - } catch (IOException e) { - return false; - } - } - - @Override - public boolean canWrite(String string) { - try { - return regularFont.getStringWidth(string) > 0; - } catch (IOException e) { - return false; - } - } - - private PDType0Font load(String resourceName) { - try { - return PDType0Font.load(pdDocument, Objects.requireNonNull(SourceSansFont.class.getResourceAsStream(resourceName)), true); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } -} diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/Hyperlink.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/Hyperlink.java index cc90ae8..2a0c687 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/Hyperlink.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/Hyperlink.java @@ -8,6 +8,7 @@ import org.xbib.graphics.pdfbox.layout.text.annotations.Annotations; import java.awt.Color; import java.util.Collections; +import java.util.List; public class Hyperlink implements ParagraphProcessor { @@ -75,7 +76,7 @@ public class Hyperlink implements ParagraphProcessor { public void process(Paragraph paragraph, Parameters parameters) { Annotations.HyperlinkAnnotation hyperlink = new Annotations.HyperlinkAnnotation(getUrl(), Annotations.HyperlinkAnnotation.LinkStyle.ul); - FontDescriptor fontDescriptor = new FontDescriptor(getFont() != null ? getFont() : parameters.getFont(), + FontDescriptor fontDescriptor = new FontDescriptor(List.of(getFont() != null ? getFont() : parameters.getFont()), getFontSize() != null ? getFontSize() : parameters.getFontSize()); paragraph.add(new AnnotatedStyledText(getText(), fontDescriptor, getColor(), getBaselineOffset(), 0, 0, Collections.singleton(hyperlink))); diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/Markup.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/Markup.java index fe9bcfb..c63af85 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/Markup.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/Markup.java @@ -3,6 +3,8 @@ package org.xbib.graphics.pdfbox.layout.table; import org.xbib.graphics.pdfbox.layout.element.Paragraph; import org.xbib.graphics.pdfbox.layout.font.Font; +import java.util.List; + public class Markup implements ParagraphProcessor { private String value; @@ -41,6 +43,6 @@ public class Markup implements ParagraphProcessor { @Override public void process(Paragraph paragraph, Parameters parameters) { float fontSize = getFontSize() != null ? getFontSize() : parameters.getFontSize(); - paragraph.addMarkup(getValue(), fontSize, font); + paragraph.addMarkup(getValue(), fontSize, List.of(font)); } } diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/NewLine.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/NewLine.java index a356fd1..3f5495c 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/NewLine.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/NewLine.java @@ -4,6 +4,8 @@ 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 NewLine implements ParagraphProcessor { private final Font font; @@ -17,7 +19,7 @@ public class NewLine implements ParagraphProcessor { @Override public void process(Paragraph paragraph, Parameters parameters) { - paragraph.add(new org.xbib.graphics.pdfbox.layout.text.NewLine(new FontDescriptor(font, fontSize))); + paragraph.add(new org.xbib.graphics.pdfbox.layout.text.NewLine(new FontDescriptor(List.of(font), fontSize))); } } diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/StyledText.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/StyledText.java index 74083b2..2f49396 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/StyledText.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/table/StyledText.java @@ -6,6 +6,7 @@ import org.xbib.graphics.pdfbox.layout.font.FontDescriptor; import org.xbib.graphics.pdfbox.layout.util.PdfUtil; import java.awt.Color; +import java.util.List; public class StyledText implements ParagraphProcessor { @@ -57,10 +58,10 @@ public class StyledText implements ParagraphProcessor { // TODO this is a complete mess to handle new lines!!! String[] lines = getText().split(PdfUtil.NEW_LINE_REGEX); for (int i = 0; i < lines.length; i++) { - FontDescriptor fontDescriptor = new FontDescriptor(actualFont, actualFontSize); + FontDescriptor fontDescriptor = new FontDescriptor(List.of(actualFont), actualFontSize); paragraph.add(new org.xbib.graphics.pdfbox.layout.text.StyledText(lines[i], fontDescriptor, actualColor, 0f, 0, 0, 0)); if (i < lines.length - 1) { - paragraph.add(new org.xbib.graphics.pdfbox.layout.text.NewLine(new FontDescriptor(actualFont, actualFontSize))); + paragraph.add(new org.xbib.graphics.pdfbox.layout.text.NewLine(new FontDescriptor(List.of(actualFont), actualFontSize))); } } } diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/Indent.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/Indent.java index 077310c..206805d 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/Indent.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/Indent.java @@ -5,13 +5,14 @@ import org.xbib.graphics.pdfbox.layout.font.FontDescriptor; import java.awt.Color; import java.io.IOException; import java.io.UncheckedIOException; +import java.util.List; /** * Control fragment that represents a indent in text. */ public class Indent extends ControlFragment { - public static final FontDescriptor DEFAULT_FONT_DESCRIPTOR = new FontDescriptor(BaseFont.HELVETICA, 11); + public static final FontDescriptor DEFAULT_FONT_DESCRIPTOR = new FontDescriptor(List.of(BaseFont.HELVETICA), 10); /** * Constant for the indentation of 0. @@ -87,21 +88,17 @@ public class Indent extends ControlFragment { } try { float indent = calculateIndent(indentWidth, indentUnit, fontDescriptor); - float textWidth = fontDescriptor.getSize() * fontDescriptor.getSelectedFont().getStringWidth(label) / 1000f; + float textWidth = fontDescriptor.getSize() * fontDescriptor.getSelectedFont(label).getStringWidth(label) / 1000f; float marginLeft = 0; float marginRight = 0; if (textWidth < indent) { switch (alignment) { - case LEFT: - marginRight = indent - textWidth; - break; - case RIGHT: - marginLeft = indent - textWidth; - break; - default: + case LEFT -> marginRight = indent - textWidth; + case RIGHT -> marginLeft = indent - textWidth; + default -> { marginLeft = (indent - textWidth) / 2f; marginRight = marginLeft; - break; + } } } styledText = new StyledText(label, fontDescriptor, getColor(), 0, marginLeft, marginRight, 0); diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/SpaceUnit.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/SpaceUnit.java index 96deae7..e5888a8 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/SpaceUnit.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/SpaceUnit.java @@ -23,11 +23,10 @@ public enum SpaceUnit { * @param size the size with respect to the unit. * @param fontDescriptor the font/size to use. * @return the size in pt. - * @throws IOException by pdfbox */ - public float toPt(float size, FontDescriptor fontDescriptor) throws IOException { + public float toPt(float size, FontDescriptor fontDescriptor) { if (this == em) { - return fontDescriptor.getSize() * fontDescriptor.getSelectedFont().getAverageFontWidth() / 1000 * size; + return fontDescriptor.getSize() * fontDescriptor.getSelectedFont(" ").getAverageFontWidth() / 1000 * size; } return size; } diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/StyledText.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/StyledText.java index 2430ae3..80d08a1 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/StyledText.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/StyledText.java @@ -124,7 +124,7 @@ public class StyledText implements TextFragment { * @throws IOException by pdfbox. */ public float getAscent() throws IOException { - return getFontDescriptor().getSize() * getFontDescriptor().getSelectedFont().getFontDescriptor().getAscent() / 1000; + return getFontDescriptor().getSize() * getFontDescriptor().getSelectedFont(text).getFontDescriptor().getAscent() / 1000; } public float getBaselineOffset() { @@ -180,7 +180,7 @@ public class StyledText implements TextFragment { private static float getWidth(FontDescriptor fontDescriptor, String text) { try { - return fontDescriptor.getSize() * fontDescriptor.getSelectedFont().getStringWidth(text) / 1000; + return fontDescriptor.getSize() * fontDescriptor.getSelectedFont(text).getStringWidth(text) / 1000; } catch (Exception e) { logger.log(Level.WARNING, e.getMessage(), e); return 0f; diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextFlow.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextFlow.java index 11bc9a9..0e6c98a 100644 --- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextFlow.java +++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextFlow.java @@ -16,7 +16,7 @@ import java.util.Map; * A text flow is a text sequence that {@link WidthRespecting respects a given * width} by word wrapping the text. The text may contain line breaks ('\n').
* In order to ease creation of styled text, this class supports a kind of - * {@link #addMarkup(String, float, Font) markup}. The following raw text + * markup. The following raw text * *
  * Markup supports *bold*, _italic_, and *even _mixed* markup_.
@@ -73,24 +73,24 @@ public class TextFlow implements TextSequence, WidthRespecting {
         return (T) cache.get(key);
     }
 
-    public void addText(String text, float fontSize, Font font) {
-        add(TextFlowUtil.createTextFlow(text, new FontDescriptor(font, fontSize), lineSpacing, rotation));
+    public void addText(String text, float fontSize, List fonts) {
+        add(TextFlowUtil.createTextFlow(text, new FontDescriptor(fonts, fontSize), lineSpacing, rotation));
     }
 
     public void addMarkup(String markup, FontDescriptor fontDescriptor) {
         add(TextFlowUtil.createTextFlowFromMarkup(markup, fontDescriptor, lineSpacing, rotation));
     }
 
-    public void addMarkup(String markup, float fontSize, Font font) {
-        add(TextFlowUtil.createTextFlowFromMarkup(markup, new FontDescriptor(font, fontSize), lineSpacing, rotation));
+    public void addMarkup(String markup, float fontSize, List fonts) {
+        add(TextFlowUtil.createTextFlowFromMarkup(markup, new FontDescriptor(fonts, fontSize), lineSpacing, rotation));
     }
 
-    public void addIndent(String label, float indentWidth, SpaceUnit indentUnit, float fontsize, Font font) {
-        add(new Indent(label, indentWidth, indentUnit, new FontDescriptor(font, fontsize)));
+    public void addIndent(String label, float indentWidth, SpaceUnit indentUnit, float fontsize, List fonts) {
+        add(new Indent(label, indentWidth, indentUnit, new FontDescriptor(fonts, fontsize)));
     }
 
-    public void addIndent(String label, float indentWidth, SpaceUnit indentUnit, float fontsize, Font font, Alignment alignment) {
-        add(new Indent(label, indentWidth, indentUnit, new FontDescriptor(font, fontsize), alignment));
+    public void addIndent(String label, float indentWidth, SpaceUnit indentUnit, float fontsize, List fonts, Alignment alignment) {
+        add(new Indent(label, indentWidth, indentUnit, new FontDescriptor(fonts, fontsize), alignment));
     }
 
     /**
diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextFlowUtil.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextFlowUtil.java
index 67b1b9e..6de16a4 100644
--- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextFlowUtil.java
+++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextFlowUtil.java
@@ -90,8 +90,7 @@ public class TextFlowUtil {
                 if (fragment instanceof ControlCharacters.ColorControlCharacter) {
                     color = ((ControlCharacters.ColorControlCharacter) fragment).getColor();
                 }
-                if (fragment instanceof AnnotationCharacters.AnnotationControlCharacter) {
-                    AnnotationCharacters.AnnotationControlCharacter annotationControlCharacter = (AnnotationCharacters.AnnotationControlCharacter) fragment;
+                if (fragment instanceof AnnotationCharacters.AnnotationControlCharacter annotationControlCharacter) {
                     if (annotationMap.containsKey(annotationControlCharacter.getAnnotationType())) {
                         annotationMap.remove(annotationControlCharacter.getAnnotationType());
                     } else {
@@ -106,8 +105,7 @@ public class TextFlowUtil {
                         metricsControl = (ControlCharacters.MetricsControlCharacter) fragment;
                     }
                 }
-                if (fragment instanceof IndentCharacters.IndentCharacter) {
-                    IndentCharacters.IndentCharacter currentIndent = (IndentCharacters.IndentCharacter) fragment;
+                if (fragment instanceof IndentCharacters.IndentCharacter currentIndent) {
                     if (currentIndent.getLevel() == 0) {
                         indentStack.clear();
                         textFlow.add(Indent.UNINDENT);
@@ -124,7 +122,7 @@ public class TextFlowUtil {
                         }
                         indentStack.push(currentIndent);
                         FontDescriptor fontDescriptor =
-                                new FontDescriptor(descriptor.getFont(), descriptor.getSize(), bold, italic);
+                                new FontDescriptor(descriptor.getFonts(), descriptor.getSize(), bold, italic);
                         textFlow.add(currentIndent.createNewIndent(fontDescriptor, color));
                     }
                 }
@@ -135,7 +133,7 @@ public class TextFlowUtil {
                     baselineOffset = metricsControl.getBaselineOffsetScale() * descriptor.getSize();
                     currentFontSize *= metricsControl.getFontScale();
                 }
-                FontDescriptor fontDescriptor = new FontDescriptor(descriptor.getFont(), currentFontSize, bold, italic);
+                FontDescriptor fontDescriptor = new FontDescriptor(descriptor.getFonts(), currentFontSize, bold, italic);
                 if (annotationMap.isEmpty()) {
                     StyledText styledText = new StyledText(fragment.toString(), fontDescriptor, color, baselineOffset, 0, 0, rotation);
                     textFlow.add(styledText);
diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextLine.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextLine.java
index d275bcf..e4e32c2 100644
--- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextLine.java
+++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextLine.java
@@ -147,8 +147,11 @@ public class TextLine implements TextSequence {
             ascent = 0f;
             for (TextFragment fragment : this) {
                 FontDescriptor fontDescriptor = fragment.getFontDescriptor();
-                float currentAscent = fontDescriptor.getSize() * fontDescriptor.getSelectedFont().getFontDescriptor().getAscent() / 1000;
-                ascent = Math.max(ascent, currentAscent);
+                String printable = fragment.getText().replaceAll("\\P{Print}|\\p{Cntrl}|\\p{Space}", "");
+                if (!printable.isEmpty()) {
+                    float currentAscent = fontDescriptor.getSize() * fontDescriptor.getSelectedFont(printable).getFontDescriptor().getAscent() / 1000;
+                    ascent = Math.max(ascent, currentAscent);
+                }
             }
             setCachedValue(ASCENT, ascent);
         }
@@ -204,13 +207,13 @@ public class TextLine implements TextSequence {
                 contentStream.setTextMatrix(matrix);
                 if (!styledText.getFontDescriptor().equals(lastFontDesc)) {
                     lastFontDesc = styledText.getFontDescriptor();
-                    contentStream.setFont(lastFontDesc.getSelectedFont(), lastFontDesc.getSize());
+                    contentStream.setFont(lastFontDesc.getSelectedFont(styledText.getText()), lastFontDesc.getSize());
                 }
                 if (!styledText.getColor().equals(lastColor)) {
                     lastColor = styledText.getColor();
                     contentStream.setNonStrokingColor(lastColor);
                 }
-                if (styledText.getText().length() > 0) {
+                if (!styledText.getText().isEmpty()) {
                     contentStream.showText(styledText.getText());
                 }
                 contentStream.endText();
diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextSequenceUtil.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextSequenceUtil.java
index 44e89eb..f9880d7 100644
--- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextSequenceUtil.java
+++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/TextSequenceUtil.java
@@ -354,13 +354,13 @@ public class TextSequenceUtil {
     /**
      * Returns the width of the given text in the given font.
      *
-     * @param text           the text to measure.
+     * @param text the text to measure.
      * @param fontDescriptor font and size.
      * @return the width of given text.
      */
     public static float getStringWidth(String text, FontDescriptor fontDescriptor) {
         try {
-            return fontDescriptor.getSize() * fontDescriptor.getSelectedFont().getStringWidth(text) / 1000;
+            return fontDescriptor.getSize() * fontDescriptor.getSelectedFont(text).getStringWidth(text) / 1000;
         } catch (IOException exception) {
             throw new UncheckedIOException(exception);
         }
diff --git a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/annotations/UnderlineAnnotationProcessor.java b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/annotations/UnderlineAnnotationProcessor.java
index 2424c3b..f293ecf 100644
--- a/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/annotations/UnderlineAnnotationProcessor.java
+++ b/graphics-pdfbox-layout/src/main/java/org/xbib/graphics/pdfbox/layout/text/annotations/UnderlineAnnotationProcessor.java
@@ -27,13 +27,12 @@ public class UnderlineAnnotationProcessor implements AnnotationProcessor {
                                      Position upperLeft,
                                      float width,
                                      float height) {
-        if (!(drawnObject instanceof StyledText)) {
+        if (!(drawnObject instanceof StyledText drawnText)) {
             return;
         }
-        StyledText drawnText = (StyledText) drawnObject;
         for (UnderlineAnnotation underlineAnnotation : drawnObject.getAnnotationsOfType(UnderlineAnnotation.class)) {
             float fontSize = drawnText.getFontDescriptor().getSize();
-            float ascent = fontSize * drawnText.getFontDescriptor().getSelectedFont().getFontDescriptor().getAscent() / 1000;
+            float ascent = fontSize * drawnText.getFontDescriptor().getSelectedFont(drawnText.getText()).getFontDescriptor().getAscent() / 1000;
             float baselineOffset = fontSize * underlineAnnotation.getBaselineOffsetScale();
             float thickness = (0.01f + fontSize * 0.05f) * underlineAnnotation.getLineWeight();
             Position start = new Position(upperLeft.getX(), upperLeft.getY() - ascent + baselineOffset);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/AlignedTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/AlignedTest.java
index e92367f..bd6eef9 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/AlignedTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/AlignedTest.java
@@ -9,6 +9,7 @@ import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import org.xbib.graphics.pdfbox.layout.util.WordBreakerFactory;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
+import java.util.List;
 
 public class AlignedTest {
 
@@ -18,22 +19,22 @@ public class AlignedTest {
                 WordBreakerFactory.LEGACY_WORD_BREAKER_CLASS_NAME);
         Document document = new Document(40, 60, 40, 60);
         Paragraph paragraph = new Paragraph();
-        paragraph.addText("This is some left aligned text", 11, BaseFont.HELVETICA);
+        paragraph.addText("This is some left aligned text", 11, List.of(BaseFont.HELVETICA));
         paragraph.setAlignment(Alignment.LEFT);
         paragraph.setMaxWidth(40);
         document.add(paragraph, VerticalLayoutHint.LEFT);
         paragraph = new Paragraph();
-        paragraph.addText("This is some centered text", 11, BaseFont.HELVETICA);
+        paragraph.addText("This is some centered text", 11, List.of(BaseFont.HELVETICA));
         paragraph.setAlignment(Alignment.CENTER);
         paragraph.setMaxWidth(40);
         document.add(paragraph, VerticalLayoutHint.CENTER);
         paragraph = new Paragraph();
-        paragraph.addText("This is some right aligned text", 11, BaseFont.HELVETICA);
+        paragraph.addText("This is some right aligned text", 11, List.of(BaseFont.HELVETICA));
         paragraph.setAlignment(Alignment.RIGHT);
         paragraph.setMaxWidth(40);
         document.add(paragraph, VerticalLayoutHint.RIGHT);
         paragraph = new Paragraph();
-        paragraph.addText("Text is right aligned, and paragraph centered", 11, BaseFont.HELVETICA);
+        paragraph.addText("Text is right aligned, and paragraph centered", 11, List.of(BaseFont.HELVETICA));
         paragraph.setAlignment(Alignment.RIGHT);
         paragraph.setMaxWidth(40);
         document.add(paragraph, VerticalLayoutHint.CENTER);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/ColumnsTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/ColumnsTest.java
index 3c99fbb..3a69fda 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/ColumnsTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/ColumnsTest.java
@@ -8,6 +8,7 @@ import org.xbib.graphics.pdfbox.layout.element.render.ColumnLayout;
 import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayoutHint;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class ColumnsTest {
 
@@ -33,18 +34,18 @@ public class ColumnsTest {
 
         Document document = new Document(40, 50, 40, 60);
         Paragraph title = new Paragraph();
-        title.addMarkup("*This Text is organized in Colums*", 20, BaseFont.TIMES);
+        title.addMarkup("*This Text is organized in Colums*", 20, List.of(BaseFont.TIMES));
         document.add(title, VerticalLayoutHint.CENTER);
         document.add(new VerticalSpacer(5));
         document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(10f));
         Paragraph paragraph1 = new Paragraph();
-        paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
+        paragraph1.addMarkup(text1, 11, List.of(BaseFont.TIMES));
         document.add(paragraph1);
         Paragraph paragraph2 = new Paragraph();
-        paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
+        paragraph2.addMarkup(text2, 12, List.of(BaseFont.HELVETICA));
         document.add(paragraph2);
         Paragraph paragraph3 = new Paragraph();
-        paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
+        paragraph3.addMarkup(text1, 8, List.of(BaseFont.COURIER));
         document.add(paragraph3);
         document.add(paragraph1);
         document.add(paragraph3);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/CustomAnnotationTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/CustomAnnotationTest.java
index b7550ba..7db743a 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/CustomAnnotationTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/CustomAnnotationTest.java
@@ -191,17 +191,17 @@ public class CustomAnnotationTest {
                 .margins(40, 60, 40, 60).portrait().build());
 
         Paragraph paragraph = new Paragraph();
-        paragraph.addText("Hello there, here is ", 10, BaseFont.HELVETICA);
+        paragraph.addText("Hello there, here is ", 10, List.of(BaseFont.HELVETICA));
 
         // now add some annotated text using our custom highlight annotation
         HighlightAnnotation annotation = new HighlightAnnotation(Color.green);
-        FontDescriptor fontDescriptor = new FontDescriptor(BaseFont.HELVETICA, 10);
+        FontDescriptor fontDescriptor = new FontDescriptor(List.of(BaseFont.HELVETICA), 10);
         AnnotatedStyledText highlightedText = new AnnotatedStyledText(
                 "highlighted text", fontDescriptor,  Color.black, 0f, 0, 0,
                 Collections.singleton(annotation));
         paragraph.add(highlightedText);
         paragraph.addText(". Do whatever you want here...strike, squiggle, whatsoever\n\n",
-                        10, BaseFont.HELVETICA);
+                        10, List.of(BaseFont.HELVETICA));
         paragraph.setMaxWidth(150);
         document.add(paragraph);
 
@@ -210,7 +210,7 @@ public class CustomAnnotationTest {
         paragraph = new Paragraph();
         paragraph.addMarkup("Hello there, here is {hl:#ffff00}highlighted text{hl}. "
                                 + "Do whatever you want here...strike, squiggle, whatsoever\n\n",
-                        10, BaseFont.HELVETICA);
+                        10, List.of(BaseFont.HELVETICA));
         paragraph.setMaxWidth(150);
         document.add(paragraph);
         document.render().save(new FileOutputStream("build/customannotation.pdf")).close();
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/CustomRendererTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/CustomRendererTest.java
index 548a8d4..68f6326 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/CustomRendererTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/CustomRendererTest.java
@@ -22,6 +22,7 @@ import org.xbib.graphics.pdfbox.layout.text.TextSequenceUtil;
 import java.awt.Color;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.List;
 
 public class CustomRendererTest {
 
@@ -51,9 +52,9 @@ public class CustomRendererTest {
         document.addRenderListener(sectionRenderer);
 
         Paragraph paragraph = new Paragraph();
-        paragraph.addMarkup(text1, 11, BaseFont.TIMES);
-        paragraph.addMarkup(text2, 12, BaseFont.HELVETICA);
-        paragraph.addMarkup(text1, 8, BaseFont.COURIER);
+        paragraph.addMarkup(text1, 11, List.of(BaseFont.TIMES));
+        paragraph.addMarkup(text2, 12, List.of(BaseFont.HELVETICA));
+        paragraph.addMarkup(text1, 8, List.of(BaseFont.COURIER));
 
         document.add(new Section(1));
         document.add(paragraph);
@@ -97,7 +98,7 @@ public class CustomRendererTest {
         @Override
         public void afterPage(RenderContext renderContext) {
             String content = String.format("Section %s, Page %s", sectionNumber, renderContext.getPageIndex() + 1);
-            FontDescriptor fontDescriptor = new FontDescriptor(BaseFont.TIMES, 11);
+            FontDescriptor fontDescriptor = new FontDescriptor(List.of(BaseFont.TIMES), 11);
             TextFlow text = TextFlowUtil.createTextFlow(content, fontDescriptor, 1.2f, 0f);
             float offset = renderContext.getPageFormat().getMarginLeft() +
                     TextSequenceUtil.getOffset(text, renderContext.getWidth(), Alignment.RIGHT);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/FramesTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/FramesTest.java
index 71fb696..a618f77 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/FramesTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/FramesTest.java
@@ -14,6 +14,7 @@ import org.xbib.graphics.pdfbox.layout.text.Alignment;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.awt.Color;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class FramesTest {
 
@@ -39,7 +40,7 @@ public class FramesTest {
 
         Document document = new Document(PageFormats.A5_PORTRAIT);
         Paragraph paragraph = new Paragraph();
-        paragraph.addMarkup("Am I living in a box?", 11, BaseFont.TIMES);
+        paragraph.addMarkup("Am I living in a box?", 11, List.of(BaseFont.TIMES));
         Frame frame = new Frame(paragraph);
         frame.setShape(new Rect());
         frame.setBorder(Color.black, new Stroke());
@@ -47,7 +48,7 @@ public class FramesTest {
         frame.setMargin(40, 40, 20, 10);
         document.add(frame, VerticalLayoutHint.CENTER);
         paragraph = new Paragraph();
-        paragraph.addMarkup(text1, 11, BaseFont.TIMES);
+        paragraph.addMarkup(text1, 11, List.of(BaseFont.TIMES));
         frame = new Frame(paragraph, 200f, null);
         frame.setShape(new Rect());
         frame.setBackgroundColor(Color.black);
@@ -55,7 +56,7 @@ public class FramesTest {
         frame.setMargin(40, 40, 20, 10);
         document.add(frame);
         paragraph = new Paragraph();
-        paragraph.addMarkup("{color:#aa00aa}*Ain't no rectangle*", 22, BaseFont.HELVETICA);
+        paragraph.addMarkup("{color:#aa00aa}*Ain't no rectangle*", 22, List.of(BaseFont.HELVETICA));
         paragraph.setAlignment(Alignment.CENTER);
         frame = new Frame(paragraph, 300f, 100f);
         frame.setShape(new Ellipse());
@@ -64,9 +65,9 @@ public class FramesTest {
         frame.setPadding(50, 0, 35, 0);
         document.add(frame);
         paragraph = new Paragraph();
-        paragraph.addMarkup("Frames also paginate, see here:\n\n", 13, BaseFont.TIMES);
-        paragraph.addMarkup(text2, 11, BaseFont.TIMES);
-        paragraph.addMarkup(text2, 11, BaseFont.TIMES);
+        paragraph.addMarkup("Frames also paginate, see here:\n\n", 13, List.of(BaseFont.TIMES));
+        paragraph.addMarkup(text2, 11, List.of(BaseFont.TIMES));
+        paragraph.addMarkup(text2, 11, List.of(BaseFont.TIMES));
         frame = new Frame(paragraph, null, null);
         frame.setShape(new RoundRect(10));
         frame.setBorder(Color.magenta, new Stroke(3));
@@ -74,8 +75,8 @@ public class FramesTest {
         frame.setPadding(20, 15, 10, 15);
         frame.setMargin(50, 50, 20, 10);
         paragraph = new Paragraph();
-        paragraph.addMarkup(text2, 11, BaseFont.TIMES);
-        paragraph.addMarkup(text2, 11, BaseFont.TIMES);
+        paragraph.addMarkup(text2, 11, List.of(BaseFont.TIMES));
+        paragraph.addMarkup(text2, 11, List.of(BaseFont.TIMES));
         frame.addDrawable(paragraph);
         document.add(frame);
         document.render().save(new FileOutputStream("build/frames.pdf")).close();
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloBarcodeTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloBarcodeTest.java
index 764dd03..64f089c 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloBarcodeTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloBarcodeTest.java
@@ -14,6 +14,7 @@ import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import org.xbib.graphics.pdfbox.layout.text.Indent;
 import org.xbib.graphics.pdfbox.layout.text.SpaceUnit;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class HelloBarcodeTest {
 
@@ -22,7 +23,7 @@ public class HelloBarcodeTest {
         Document document = new Document(PageFormats.A4_PORTRAIT);
         Paragraph paragraph = new Paragraph();
         paragraph.add(new Indent(50, SpaceUnit.pt));
-        paragraph.addMarkup("Hello Barcode\n", 12, BaseFont.HELVETICA);
+        paragraph.addMarkup("Hello Barcode\n", 12, List.of(BaseFont.HELVETICA));
         document.add(paragraph);
         Symbol symbol = new Code3Of9();
         symbol.setContent("1234567890");
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloCatTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloCatTest.java
index fb339e8..ccbd051 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloCatTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloCatTest.java
@@ -8,6 +8,7 @@ import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayoutHint;
 import org.xbib.graphics.pdfbox.layout.text.Alignment;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.io.FileOutputStream;
+import java.util.List;
 import javax.imageio.ImageIO;
 
 public class HelloCatTest {
@@ -16,7 +17,7 @@ public class HelloCatTest {
     public void test() throws Exception {
         Document document = new Document();
         Paragraph paragraph = new Paragraph();
-        paragraph.addText("Hello Cat", 12, BaseFont.HELVETICA);
+        paragraph.addText("Hello Cat", 12, List.of(BaseFont.HELVETICA));
         document.add(paragraph);
         ImageElement imageElement = new ImageElement();
         imageElement.setImage(ImageIO.read(getClass().getResourceAsStream("cat.jpg")));
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloDocTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloDocTest.java
index 8b6e4e9..bba9e31 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloDocTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloDocTest.java
@@ -5,6 +5,7 @@ import org.xbib.graphics.pdfbox.layout.element.Document;
 import org.xbib.graphics.pdfbox.layout.element.Paragraph;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class HelloDocTest {
 
@@ -12,7 +13,7 @@ public class HelloDocTest {
     public void test() throws Exception {
         Document document = new Document(40, 60, 40, 60);
         Paragraph paragraph = new Paragraph();
-        paragraph.addText("Hello Document", 20, BaseFont.HELVETICA);
+        paragraph.addText("Hello Document", 20, List.of(BaseFont.HELVETICA));
         document.add(paragraph);
         document.render().save(new FileOutputStream("build/hellodoc.pdf")).close();
     }
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloNotoSansCJKFontTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloNotoSansCJKFontTest.java
index 90fcb3c..be8b18e 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloNotoSansCJKFontTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloNotoSansCJKFontTest.java
@@ -5,19 +5,19 @@ import org.xbib.graphics.pdfbox.layout.element.Document;
 import org.xbib.graphics.pdfbox.layout.element.PageFormats;
 import org.xbib.graphics.pdfbox.layout.element.Paragraph;
 import org.xbib.graphics.pdfbox.layout.font.Font;
-import org.xbib.graphics.pdfbox.layout.font.NotoSansCJKFont;
-import org.xbib.graphics.pdfbox.layout.font.NotoSansFont;
 import org.xbib.graphics.pdfbox.layout.text.Indent;
 import org.xbib.graphics.pdfbox.layout.text.SpaceUnit;
 
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class HelloNotoSansCJKFontTest {
 
     @Test
     public void testDocumentOne() throws Exception {
         Document document = new Document(PageFormats.A4_PORTRAIT);
-        Font font = new NotoSansCJKFont(document);
+        document.registerNotoSansCJKSCFont();
+        List font = List.of(document.getFont("notosanscjksc"));
         Paragraph paragraph = new Paragraph();
         paragraph.add(new Indent(32, SpaceUnit.pt));
         paragraph.addMarkup("Hello Noto Sans CJK Regular\n", 12, font);
@@ -36,7 +36,8 @@ public class HelloNotoSansCJKFontTest {
     @Test
     public void testDocumentTwo() throws Exception {
         Document document = new Document(PageFormats.A4_PORTRAIT);
-        Font font = new NotoSansCJKFont(document);
+        document.registerNotoSansCJKSCFont();
+        List font = List.of(document.getFont("notosanscjksc"));
         Paragraph paragraph = new Paragraph();
         paragraph.add(new Indent(32, SpaceUnit.pt));
         paragraph.addMarkup("Hello Noto Sans CJK Regular 2\n", 12, font);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloNotoSansFontTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloNotoSansFontTest.java
index fb38138..a9c8956 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloNotoSansFontTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloNotoSansFontTest.java
@@ -5,17 +5,18 @@ import org.xbib.graphics.pdfbox.layout.element.Document;
 import org.xbib.graphics.pdfbox.layout.element.PageFormats;
 import org.xbib.graphics.pdfbox.layout.element.Paragraph;
 import org.xbib.graphics.pdfbox.layout.font.Font;
-import org.xbib.graphics.pdfbox.layout.font.NotoSansFont;
 import org.xbib.graphics.pdfbox.layout.text.Indent;
 import org.xbib.graphics.pdfbox.layout.text.SpaceUnit;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class HelloNotoSansFontTest {
 
     @Test
     public void testDocumentOne() throws Exception {
         Document document = new Document(PageFormats.A4_PORTRAIT);
-        Font font = new NotoSansFont(document);
+        document.registerNotoSansFont();
+        List font = List.of(document.getFont("notosans"));
         Paragraph paragraph = new Paragraph();
         paragraph.add(new Indent(32, SpaceUnit.pt));
         paragraph.addMarkup("Hello Noto Regular\n", 12, font);
@@ -35,7 +36,8 @@ public class HelloNotoSansFontTest {
     @Test
     public void testDocumentTwo() throws Exception {
         Document document = new Document(PageFormats.A4_PORTRAIT);
-        Font font = new NotoSansFont(document);
+        document.registerNotoSansFont();
+        List font = List.of(document.getFont("notosans"));
         Paragraph paragraph = new Paragraph();
         paragraph.add(new Indent(32, SpaceUnit.pt));
         paragraph.addMarkup("Hello Noto Regular 2\n", 12, font);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloOpenSansFontTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloOpenSansFontTest.java
index 1f87943..9357840 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloOpenSansFontTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloOpenSansFontTest.java
@@ -5,18 +5,19 @@ import org.xbib.graphics.pdfbox.layout.element.Document;
 import org.xbib.graphics.pdfbox.layout.element.PageFormats;
 import org.xbib.graphics.pdfbox.layout.element.Paragraph;
 import org.xbib.graphics.pdfbox.layout.font.Font;
-import org.xbib.graphics.pdfbox.layout.font.OpenSansFont;
 import org.xbib.graphics.pdfbox.layout.text.Indent;
 import org.xbib.graphics.pdfbox.layout.text.SpaceUnit;
 
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class HelloOpenSansFontTest {
 
     @Test
     public void testDocumentOne() throws Exception {
         Document document = new Document(PageFormats.A4_PORTRAIT);
-        Font font = new OpenSansFont(document);
+        document.registerOpenSansFont();
+        List font = List.of(document.getFont("opensans"));
         Paragraph paragraph = new Paragraph();
         paragraph.add(new Indent(32, SpaceUnit.pt));
         paragraph.addMarkup("Hello Open Sans Regular\n", 12, font);
@@ -37,7 +38,8 @@ public class HelloOpenSansFontTest {
     @Test
     public void testDocumentTwo() throws Exception {
         Document document = new Document(PageFormats.A4_PORTRAIT);
-        Font font = new OpenSansFont(document);
+        document.registerOpenSansFont();
+        List font = List.of(document.getFont("opensans"));
         Paragraph paragraph = new Paragraph();
         paragraph.add(new Indent(32, SpaceUnit.pt));
         paragraph.addMarkup("Hello Open Sans Regular 2\n", 12, font);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloSourceSansFontTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloSourceSansFontTest.java
index 7ddce7e..3d73259 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloSourceSansFontTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/HelloSourceSansFontTest.java
@@ -5,18 +5,19 @@ import org.xbib.graphics.pdfbox.layout.element.Document;
 import org.xbib.graphics.pdfbox.layout.element.PageFormats;
 import org.xbib.graphics.pdfbox.layout.element.Paragraph;
 import org.xbib.graphics.pdfbox.layout.font.Font;
-import org.xbib.graphics.pdfbox.layout.font.SourceSansFont;
 import org.xbib.graphics.pdfbox.layout.text.Indent;
 import org.xbib.graphics.pdfbox.layout.text.SpaceUnit;
 
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class HelloSourceSansFontTest {
 
     @Test
     public void testDocumentOne() throws Exception {
         Document document = new Document(PageFormats.A4_PORTRAIT);
-        Font font = new SourceSansFont(document);
+        document.registerSourceSansFont();
+        List font = List.of(document.getFont("sourcesans"));
         Paragraph paragraph = new Paragraph();
         paragraph.add(new Indent(32, SpaceUnit.pt));
         paragraph.addMarkup("Hello Source Sans Regular\n", 12, font);
@@ -37,7 +38,8 @@ public class HelloSourceSansFontTest {
     @Test
     public void testDocumentTwo() throws Exception {
         Document document = new Document(PageFormats.A4_PORTRAIT);
-        Font font = new SourceSansFont(document);
+        document.registerSourceSansFont();
+        List font = List.of(document.getFont("sourcesans"));
         Paragraph paragraph = new Paragraph();
         paragraph.add(new Indent(32, SpaceUnit.pt));
         paragraph.addMarkup("Hello Source Sans Regular 2\n", 12, font);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/IndentationTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/IndentationTest.java
index 4ef3ea8..43545f8 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/IndentationTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/IndentationTest.java
@@ -13,6 +13,7 @@ import org.xbib.graphics.pdfbox.layout.util.Enumerators.LowerCaseAlphabeticEnume
 import org.xbib.graphics.pdfbox.layout.util.Enumerators.LowerCaseRomanEnumerator;
 import org.xbib.graphics.pdfbox.layout.util.Enumerators.RomanEnumerator;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class IndentationTest {
 
@@ -23,68 +24,68 @@ public class IndentationTest {
         Document document = new Document(40, 60, 40, 60);
         Paragraph paragraph = new Paragraph();
         paragraph.addMarkup("This is an example for the new indent feature. Let's do some empty space indentation:\n",
-                11, BaseFont.TIMES);
+                11, List.of(BaseFont.TIMES));
         paragraph.add(new Indent(50, SpaceUnit.pt));
-        paragraph.addMarkup("Here we go indented.\n", 11, BaseFont.TIMES);
+        paragraph.addMarkup("Here we go indented.\n", 11, List.of(BaseFont.TIMES));
         paragraph.addMarkup("The Indentation holds for the rest of the paragraph, or... \n",
-                11, BaseFont.TIMES);
+                11, List.of(BaseFont.TIMES));
         paragraph.add(new Indent(70, SpaceUnit.pt));
-        paragraph.addMarkup("any new indent comes.\n", 11, BaseFont.TIMES);
+        paragraph.addMarkup("any new indent comes.\n", 11, List.of(BaseFont.TIMES));
         document.add(paragraph);
         paragraph = new Paragraph();
-        paragraph.addMarkup("New paragraph, now indentation is gone. But we can indent with a label also:\n", 11, BaseFont.TIMES);
-        paragraph.addIndent("This is some label", 100, SpaceUnit.pt, 11, BaseFont.TIMES);
-        paragraph.addMarkup("Here we go indented.\n", 11, BaseFont.TIMES);
-        paragraph.addMarkup("And again, the Indentation holds for the rest of the paragraph, or any new indent comes.\nLabels can be aligned:\n", 11, BaseFont.TIMES);
-        paragraph.addIndent("Left", 100, SpaceUnit.pt, 11, BaseFont.TIMES, Alignment.LEFT);
-        paragraph.addMarkup("Indent with label aligned to the left.\n", 11, BaseFont.TIMES);
-        paragraph.addIndent("Center", 100, SpaceUnit.pt, 11, BaseFont.TIMES, Alignment.CENTER);
-        paragraph.addMarkup("Indent with label aligned to the center.\n", 11, BaseFont.TIMES);
-        paragraph.addIndent("Right", 100, SpaceUnit.pt, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("Indent with label aligned to the right.\n", 11, BaseFont.TIMES);
+        paragraph.addMarkup("New paragraph, now indentation is gone. But we can indent with a label also:\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent("This is some label", 100, SpaceUnit.pt, 11, List.of(BaseFont.TIMES));
+        paragraph.addMarkup("Here we go indented.\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addMarkup("And again, the Indentation holds for the rest of the paragraph, or any new indent comes.\nLabels can be aligned:\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent("Left", 100, SpaceUnit.pt, 11, List.of(BaseFont.TIMES), Alignment.LEFT);
+        paragraph.addMarkup("Indent with label aligned to the left.\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent("Center", 100, SpaceUnit.pt, 11, List.of(BaseFont.TIMES), Alignment.CENTER);
+        paragraph.addMarkup("Indent with label aligned to the center.\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent("Right", 100, SpaceUnit.pt, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("Indent with label aligned to the right.\n", 11, List.of(BaseFont.TIMES));
         document.add(paragraph);
         paragraph = new Paragraph();
-        paragraph.addMarkup("So, what can you do with that? How about lists:\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(bulletOdd, 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("This is a list item\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(bulletOdd, 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("Another list item\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(bulletEven, 8, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("Sub list item\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(bulletOdd, 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("And yet another one\n", 11, BaseFont.TIMES);
+        paragraph.addMarkup("So, what can you do with that? How about lists:\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(bulletOdd, 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("This is a list item\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(bulletOdd, 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("Another list item\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(bulletEven, 8, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("Sub list item\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(bulletOdd, 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("And yet another one\n", 11, List.of(BaseFont.TIMES));
         document.add(paragraph);
 
         paragraph = new Paragraph();
-        paragraph.addMarkup("Also available with indents: Enumerators:\n", 11, BaseFont.TIMES);
+        paragraph.addMarkup("Also available with indents: Enumerators:\n", 11, List.of(BaseFont.TIMES));
         RomanEnumerator e1 = new RomanEnumerator();
         LowerCaseAlphabeticEnumerator e2 = new LowerCaseAlphabeticEnumerator();
-        paragraph.addIndent(e1.next() + ". ", 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("First item\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(e1.next() + ". ", 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("Second item\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(e2.next() + ") ", 8, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("A sub item\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(e2.next() + ") ", 8, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("Another sub item\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(e1.next() + ". ", 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("Third item\n", 11, BaseFont.TIMES);
+        paragraph.addIndent(e1.next() + ". ", 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("First item\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(e1.next() + ". ", 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("Second item\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(e2.next() + ") ", 8, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("A sub item\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(e2.next() + ") ", 8, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("Another sub item\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(e1.next() + ". ", 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("Third item\n", 11, List.of(BaseFont.TIMES));
         document.add(paragraph);
 
         paragraph = new Paragraph();
         paragraph.addMarkup("The following types are built in:\n", 11,
-                BaseFont.TIMES);
-        paragraph.addIndent(new ArabicEnumerator().next() + " ", 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("ArabicEnumerator\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(new RomanEnumerator().next() + " ", 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("RomanEnumerator\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(new LowerCaseRomanEnumerator().next() + " ", 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("LowerCaseRomanEnumerator\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(new AlphabeticEnumerator().next() + " ", 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
-        paragraph.addMarkup("AlphabeticEnumerator\n", 11, BaseFont.TIMES);
-        paragraph.addIndent(new LowerCaseAlphabeticEnumerator().next() + " ", 4, SpaceUnit.em, 11, BaseFont.TIMES, Alignment.RIGHT);
+                List.of(BaseFont.TIMES));
+        paragraph.addIndent(new ArabicEnumerator().next() + " ", 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("ArabicEnumerator\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(new RomanEnumerator().next() + " ", 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("RomanEnumerator\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(new LowerCaseRomanEnumerator().next() + " ", 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("LowerCaseRomanEnumerator\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(new AlphabeticEnumerator().next() + " ", 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
+        paragraph.addMarkup("AlphabeticEnumerator\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addIndent(new LowerCaseAlphabeticEnumerator().next() + " ", 4, SpaceUnit.em, 11, List.of(BaseFont.TIMES), Alignment.RIGHT);
         paragraph.addMarkup("LowerCaseAlphabeticEnumerator\n", 11,
-                BaseFont.TIMES);
+                List.of(BaseFont.TIMES));
         document.add(paragraph);
         paragraph = new Paragraph();
         String text1 = "For your convenience, you can do all that much easier with markup, e.g. simple indentation\n"
@@ -104,7 +105,7 @@ public class IndentationTest {
                 + "-#{I ->:5}Another list item\n"
                 + " -#{a ~:30pt}A sub list item\n"
                 + "-#{I ->:5}And yet another one\n\n";
-        paragraph.addMarkup(text1, 11, BaseFont.TIMES);
+        paragraph.addMarkup(text1, 11, List.of(BaseFont.TIMES));
         document.add(paragraph);
         document.render().save(new FileOutputStream("build/indentation.pdf")).close();
     }
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LandscapeTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LandscapeTest.java
index d0f988f..45e845d 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LandscapeTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LandscapeTest.java
@@ -11,11 +11,12 @@ import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayout;
 import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayoutHint;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class LandscapeTest {
 
     @Test
-    public void main() throws Exception {
+    public void test() throws Exception {
         String text1 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, "
                 + "sed diam nonumy eirmod tempor invidunt ut labore et dolore magna "
                 + "aliquyam erat, _sed diam_ voluptua. At vero eos et *accusam et justo* "
@@ -35,16 +36,16 @@ public class LandscapeTest {
                 + "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n";
 
         Paragraph paragraph1 = new Paragraph();
-        paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
+        paragraph1.addMarkup(text1, 11, List.of(BaseFont.TIMES));
         Paragraph paragraph2 = new Paragraph();
-        paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
+        paragraph2.addMarkup(text2, 12, List.of(BaseFont.HELVETICA));
         Paragraph paragraph3 = new Paragraph();
-        paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
+        paragraph3.addMarkup(text1, 8, List.of(BaseFont.COURIER));
 
         Paragraph titleA4 = new Paragraph();
-        titleA4.addMarkup("*Format A4 in Portrait*", 20, BaseFont.TIMES);
+        titleA4.addMarkup("*Format A4 in Portrait*", 20, List.of(BaseFont.TIMES));
         Paragraph titleA5 = new Paragraph();
-        titleA5.addMarkup("*Format A5 in Landscape*", 20, BaseFont.TIMES);
+        titleA5.addMarkup("*Format A5 in Landscape*", 20, List.of(BaseFont.TIMES));
 
         PageFormat a5_landscape = PageFormat.builder().A5().landscape().margins(10, 50, 0, 30).build();
         PageFormat a4_portrait = PageFormat.builder().margins(40, 50, 40, 60).build();
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LetterTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LetterTest.java
index af88502..36d4242 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LetterTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LetterTest.java
@@ -12,6 +12,7 @@ import org.xbib.graphics.pdfbox.layout.position.Position;
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.FileOutputStream;
+import java.util.List;
 import javax.imageio.ImageIO;
 
 public class LetterTest {
@@ -39,17 +40,16 @@ public class LetterTest {
         document.add(new VerticalSpacer(100));
 
         Paragraph paragraph = new Paragraph();
-        paragraph.addText("Blubberhausen, 01.04.2016", 11, BaseFont.HELVETICA);
+        paragraph.addText("Blubberhausen, 01.04.2016", 11, List.of(BaseFont.HELVETICA));
         document.add(paragraph, new VerticalLayoutHint(Alignment.RIGHT, 0, 0,
                 0, 0, true));
 
         paragraph = new Paragraph();
         String address = "Ralf Stuckert\nAm Hollergraben 24\n67346 Blubberhausen";
-        paragraph.addText(address, 11, BaseFont.HELVETICA);
+        paragraph.addText(address, 11, List.of(BaseFont.HELVETICA));
         document.add(paragraph);
 
         paragraph = new Paragraph();
-        paragraph.addMarkup("*Labore et dolore magna aliquyam erat*", 11, BaseFont.HELVETICA);
         document.add(paragraph, new VerticalLayoutHint(Alignment.LEFT, 0, 0,
                 40, 20));
 
@@ -63,21 +63,21 @@ public class LetterTest {
                 + "At vero eos et accusam* et justo duo dolores et ea rebum. Stet clita kasd "
                 + "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n\n";
         paragraph = new Paragraph();
-        paragraph.addMarkup(text, 11, BaseFont.HELVETICA);
+        paragraph.addMarkup(text, 11, List.of(BaseFont.HELVETICA));
         document.add(paragraph);
 
         document.add(paragraph);
 
         paragraph = new Paragraph();
         paragraph.addMarkup("Dolore magna aliquyam erat\nRalf Stuckert", 11,
-                BaseFont.HELVETICA);
+                List.of(BaseFont.HELVETICA));
         document.add(paragraph, new VerticalLayoutHint(Alignment.LEFT, 60, 0,
                 40, 0));
 
         paragraph = new Paragraph();
         paragraph.addMarkup("*Sanctus est:* Lorem ipsum dolor consetetur "
                         + "sadipscing sed diam nonumy eirmod tempor invidunt", 6,
-                BaseFont.TIMES);
+                List.of(BaseFont.TIMES));
         paragraph.setAbsolutePosition(new Position(hMargin, vMargin));
         document.add(paragraph);
 
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LineSpacingTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LineSpacingTest.java
index e5dbf33..5995235 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LineSpacingTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LineSpacingTest.java
@@ -7,6 +7,7 @@ import org.xbib.graphics.pdfbox.layout.element.Paragraph;
 import org.xbib.graphics.pdfbox.layout.element.render.ColumnLayout;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class LineSpacingTest {
 
@@ -30,7 +31,7 @@ public class LineSpacingTest {
         // use a bigger line spacing to visualize the effects of line spacing more drastically
         left.setLineSpacing(1.5f);
         left.setMaxWidth(document.getPageWidth() / 2);
-        left.addMarkup(text, 11, BaseFont.TIMES);
+        left.addMarkup(text, 11, List.of(BaseFont.TIMES));
         document.add(left);
         document.add(left);
         document.add(left);
@@ -38,7 +39,7 @@ public class LineSpacingTest {
         Paragraph right = new Paragraph();
         right.setLineSpacing(1.5f);
         right.setMaxWidth(document.getPageWidth() / 2);
-        right.addMarkup(text, 11, BaseFont.TIMES);
+        right.addMarkup(text, 11, List.of(BaseFont.TIMES));
         document.add(right);
 
         document.add(right);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LinksTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LinksTest.java
index 4453008..54f8643 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LinksTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LinksTest.java
@@ -5,6 +5,7 @@ import org.xbib.graphics.pdfbox.layout.element.Document;
 import org.xbib.graphics.pdfbox.layout.element.Paragraph;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class LinksTest {
 
@@ -31,25 +32,25 @@ public class LinksTest {
         Document document = new Document(40, 60, 40, 60);
 
         Paragraph paragraph0 = new Paragraph();
-        paragraph0.addMarkup("This is a link to {link[https://github.com/ralfstuckert/pdfbox-layout]}PDFBox-Layout{link}.\n\n", 11, BaseFont.TIMES);
-        paragraph0.addMarkup("Now the same link with color instead of underline {color:#ff5000}{link:none[https://github.com/ralfstuckert/pdfbox-layout]}PDFBox-Layout{link}{color:#000000}.\n\n", 11, BaseFont.TIMES);
-        paragraph0.addMarkup("And here comes a link to an internal anchor name {color:#ff5000}{link[#hello]}hello{link}{color:#000000}.\n\n", 11, BaseFont.TIMES);
+        paragraph0.addMarkup("This is a link to {link[https://xbib.org]}PDFBox-Layout{link}.\n\n", 11, List.of(BaseFont.TIMES));
+        paragraph0.addMarkup("Now the same link with color instead of underline {color:#ff5000}{link:none[https://xbib.org]}PDFBox-Layout{link}{color:#000000}.\n\n", 11, List.of(BaseFont.TIMES));
+        paragraph0.addMarkup("And here comes a link to an internal anchor name {color:#ff5000}{link[#hello]}hello{link}{color:#000000}.\n\n", 11, List.of(BaseFont.TIMES));
         document.add(paragraph0);
 
         Paragraph paragraph1 = new Paragraph();
-        paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
+        paragraph1.addMarkup(text1, 11, List.of(BaseFont.TIMES));
         document.add(paragraph1);
 
         Paragraph paragraph2 = new Paragraph();
-        paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
+        paragraph2.addMarkup(text2, 12, List.of(BaseFont.HELVETICA));
         document.add(paragraph2);
 
         Paragraph paragraph3 = new Paragraph();
-        paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
+        paragraph3.addMarkup(text1, 8, List.of(BaseFont.COURIER));
         document.add(paragraph3);
 
         Paragraph paragraph4 = new Paragraph();
-        paragraph4.addMarkup("\n\n{anchor:hello}Here{anchor} comes the internal anchor named *hello*\n\n", 15, BaseFont.COURIER);
+        paragraph4.addMarkup("\n\n{anchor:hello}Here{anchor} comes the internal anchor named *hello*\n\n", 15, List.of(BaseFont.COURIER));
         document.add(paragraph1);
         document.add(paragraph3);
         document.add(paragraph1);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/ListenerTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/ListenerTest.java
index 4aa0d70..0abba7e 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/ListenerTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/ListenerTest.java
@@ -13,6 +13,7 @@ import org.xbib.graphics.pdfbox.layout.text.TextFlow;
 import org.xbib.graphics.pdfbox.layout.text.TextFlowUtil;
 import org.xbib.graphics.pdfbox.layout.text.TextSequenceUtil;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class ListenerTest {
 
@@ -47,7 +48,7 @@ public class ListenerTest {
             @Override
             public void afterPage(RenderContext renderContext) {
                 String content = String.format("Page %s", renderContext.getPageIndex() + 1);
-                FontDescriptor fontDescriptor = new FontDescriptor(BaseFont.HELVETICA, 11);
+                FontDescriptor fontDescriptor = new FontDescriptor(List.of(BaseFont.HELVETICA), 11);
                 TextFlow text = TextFlowUtil.createTextFlow(content, fontDescriptor, 1.2f, 0f);
                 float offset = renderContext.getPageFormat().getMarginLeft()
                         + TextSequenceUtil.getOffset(text,
@@ -58,9 +59,9 @@ public class ListenerTest {
         });
 
         Paragraph paragraph = new Paragraph();
-        paragraph.addMarkup(text1, 11, BaseFont.TIMES);
-        paragraph.addMarkup(text2, 12, BaseFont.HELVETICA);
-        paragraph.addMarkup(text1, 8, BaseFont.COURIER);
+        paragraph.addMarkup(text1, 11, List.of(BaseFont.TIMES));
+        paragraph.addMarkup(text2, 12, List.of(BaseFont.HELVETICA));
+        paragraph.addMarkup(text1, 8, List.of(BaseFont.COURIER));
 
         document.add(paragraph);
         document.add(paragraph);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LowLevelText.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LowLevelText.java
index c1d25fc..3c27e90 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LowLevelText.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/LowLevelText.java
@@ -21,6 +21,7 @@ import org.xbib.graphics.pdfbox.layout.text.annotations.AnnotationDrawListener;
 import java.awt.Color;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.List;
 
 public class LowLevelText {
 
@@ -56,10 +57,10 @@ public class LowLevelText {
 
         TextFlow text = TextFlowUtil.createTextFlowFromMarkup(
                         "Hello *bold _italic bold-end* italic-end_. Eirmod\ntempor invidunt ut \\*labore",
-                        new FontDescriptor(BaseFont.TIMES, 11), 1.2f, 0f);
-        text.addText("Spongebob", 11, BaseFont.COURIER);
-        text.addText(" is ", 20, BaseFont.HELVETICA);
-        text.addText("cool", 7, BaseFont.HELVETICA);
+                        new FontDescriptor(List.of(BaseFont.TIMES), 11), 1.2f, 0f);
+        text.addText("Spongebob", 11, List.of(BaseFont.COURIER));
+        text.addText(" is ", 20, List.of(BaseFont.HELVETICA));
+        text.addText("cool", 7, List.of(BaseFont.HELVETICA));
         text.setMaxWidth(100);
         float xOffset = TextSequenceUtil.getOffset(text, pageWidth,
                 Alignment.RIGHT);
@@ -78,7 +79,7 @@ public class LowLevelText {
                 + "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n";
 
         text = new TextFlow();
-        text.addMarkup(textBlock, 8, BaseFont.COURIER);
+        text.addMarkup(textBlock, 8, List.of(BaseFont.COURIER));
         text.setMaxWidth(200);
         xOffset = TextSequenceUtil.getOffset(text, pageWidth, Alignment.CENTER);
         text.drawText(contentStream, new Position(xOffset, pageHeight - 100), null,
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MarginTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MarginTest.java
index ef37e3e..800c023 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MarginTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MarginTest.java
@@ -7,6 +7,7 @@ import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayoutHint;
 import org.xbib.graphics.pdfbox.layout.text.Alignment;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class MarginTest {
 
@@ -36,17 +37,17 @@ public class MarginTest {
 
         Document document = new Document(40, 60, 40, 60);
         Paragraph paragraph = new Paragraph();
-        paragraph.addText(text1, 11, BaseFont.HELVETICA);
+        paragraph.addText(text1, 11, List.of(BaseFont.HELVETICA));
         document.add(paragraph, new VerticalLayoutHint(Alignment.LEFT, 0, 100,
                 100, 100));
 
         paragraph = new Paragraph();
-        paragraph.addText(text2, 11, BaseFont.HELVETICA);
+        paragraph.addText(text2, 11, List.of(BaseFont.HELVETICA));
         document.add(paragraph, new VerticalLayoutHint(Alignment.RIGHT, 0, 50,
                 0, 0));
 
         paragraph = new Paragraph();
-        paragraph.addText(text3, 11, BaseFont.HELVETICA);
+        paragraph.addText(text3, 11, List.of(BaseFont.HELVETICA));
         document.add(paragraph, new VerticalLayoutHint(Alignment.RIGHT, 150,
                 150, 20, 0));
         document.render().save(new FileOutputStream("build/margin.pdf")).close();
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MarkupTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MarkupTest.java
index 35bd79a..b83e3f8 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MarkupTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MarkupTest.java
@@ -7,6 +7,7 @@ import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayoutHint;
 import org.xbib.graphics.pdfbox.layout.text.Alignment;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class MarkupTest {
 
@@ -25,26 +26,26 @@ public class MarkupTest {
         Document document = new Document(40, 60, 40, 60);
 
         Paragraph paragraph = new Paragraph();
-        paragraph.addMarkup(text1, 11, BaseFont.TIMES);
+        paragraph.addMarkup(text1, 11, List.of(BaseFont.TIMES));
         document.add(paragraph);
 
         paragraph = new Paragraph();
         paragraph.addMarkup("Markup supports *bold*, _italic_, and *even _mixed* markup_.\n\n",
-                11, BaseFont.TIMES);
+                11, List.of(BaseFont.TIMES));
         paragraph.addMarkup("Escape \\* with \\\\\\* and \\_ with \\\\\\_ in markup.\n\n",
-                11, BaseFont.TIMES);
+                11, List.of(BaseFont.TIMES));
         paragraph.addMarkup("And now also {color:#ff0000}c{color:#00ff00}o{color:#0000ff}l{color:#00cccc}o{color:#cc00cc}r{color:#000000}",
-                11, BaseFont.TIMES);
+                11, List.of(BaseFont.TIMES));
         paragraph.addMarkup(" , {_}subscript{_} and {^}superscript{^}.\n\n",
-                11, BaseFont.TIMES);
+                11, List.of(BaseFont.TIMES));
         paragraph.addMarkup("You can alternate the position and thickness of an __underline__, "
                                 + "so you may also use this to __{0.25:}strike through__ or blacken __{0.25:20}things__ out\n\n",
-                        11, BaseFont.TIMES);
+                        11, List.of(BaseFont.TIMES));
         document.add(paragraph, new VerticalLayoutHint(Alignment.LEFT, 0, 0, 30, 0));
 
         paragraph = new Paragraph();
-        paragraph.addMarkup("And here comes a link to an internal anchor name {color:#ff5000}{link[#hello]}hello{link}{color:#000000}.\n\n", 11, BaseFont.TIMES);
-        paragraph.addMarkup("\n\n{anchor:hello}Here{anchor} comes the internal anchor named *hello*\n\n", 11, BaseFont.COURIER);
+        paragraph.addMarkup("And here comes a link to an internal anchor name {color:#ff5000}{link[#hello]}hello{link}{color:#000000}.\n\n", 11, List.of(BaseFont.TIMES));
+        paragraph.addMarkup("\n\n{anchor:hello}Here{anchor} comes the internal anchor named *hello*\n\n", 11, List.of(BaseFont.COURIER));
         document.add(paragraph);
 
         paragraph = new Paragraph();
@@ -65,7 +66,7 @@ public class MarkupTest {
                 + "-#{I ->:5}Another list item\n"
                 + " -#{a ~:30pt}A sub list item\n"
                 + "-#{I ->:5}And yet another one\n\n";
-        paragraph.addMarkup(text1, 11, BaseFont.TIMES);
+        paragraph.addMarkup(text1, 11, List.of(BaseFont.TIMES));
         document.add(paragraph);
 
         document.render().save( new FileOutputStream("build/markup.pdf")).close();
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MultiplePagesTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MultiplePagesTest.java
index 600d885..09bf996 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MultiplePagesTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/MultiplePagesTest.java
@@ -5,6 +5,7 @@ import org.xbib.graphics.pdfbox.layout.element.Document;
 import org.xbib.graphics.pdfbox.layout.element.Paragraph;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class MultiplePagesTest {
 
@@ -31,15 +32,15 @@ public class MultiplePagesTest {
         Document document = new Document(40, 60, 40, 60);
 
         Paragraph paragraph1 = new Paragraph();
-        paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
+        paragraph1.addMarkup(text1, 11, List.of(BaseFont.TIMES));
         document.add(paragraph1);
 
         Paragraph paragraph2 = new Paragraph();
-        paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
+        paragraph2.addMarkup(text2, 12, List.of(BaseFont.HELVETICA));
         document.add(paragraph2);
 
         Paragraph paragraph3 = new Paragraph();
-        paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
+        paragraph3.addMarkup(text1, 8, List.of(BaseFont.COURIER));
         document.add(paragraph3);
 
         document.add(paragraph1);
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/PageFormatRotationTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/PageFormatRotationTest.java
index cca3141..f8db9aa 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/PageFormatRotationTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/PageFormatRotationTest.java
@@ -11,6 +11,7 @@ import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayout;
 import org.xbib.graphics.pdfbox.layout.element.render.VerticalLayoutHint;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 import java.io.FileOutputStream;
+import java.util.List;
 
 public class PageFormatRotationTest {
 
@@ -35,16 +36,16 @@ public class PageFormatRotationTest {
                 + "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n";
 
         Paragraph paragraph1 = new Paragraph();
-        paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
+        paragraph1.addMarkup(text1, 11, List.of(BaseFont.TIMES));
         Paragraph paragraph2 = new Paragraph();
-        paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
+        paragraph2.addMarkup(text2, 12, List.of(BaseFont.HELVETICA));
         Paragraph paragraph3 = new Paragraph();
-        paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
+        paragraph3.addMarkup(text1, 8, List.of(BaseFont.COURIER));
 
         Paragraph titleA4 = new Paragraph();
-        titleA4.addMarkup("*Format A4 Landscape*", 20, BaseFont.TIMES);
+        titleA4.addMarkup("*Format A4 Landscape*", 20, List.of(BaseFont.TIMES));
         Paragraph titleA5 = new Paragraph();
-        titleA5.addMarkup("*Format A4 Landscape rotated by -90 degrees*", 20, BaseFont.TIMES);
+        titleA5.addMarkup("*Format A4 Landscape rotated by -90 degrees*", 20, List.of(BaseFont.TIMES));
 
         PageFormat a4_landscape = PageFormat.builder().margins(40, 50, 40, 60).landscape().build();
         PageFormat a4_landscape_rotated = PageFormat.builder().margins(40, 50, 40, 60).landscape().rotation(-90).build();
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/Section.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/Section.java
index 1fec7f4..173490a 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/Section.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/Section.java
@@ -3,13 +3,15 @@ package org.xbib.graphics.pdfbox.layout.test;
 import org.xbib.graphics.pdfbox.layout.element.Paragraph;
 import org.xbib.graphics.pdfbox.layout.font.BaseFont;
 
+import java.util.List;
+
 public class Section extends Paragraph {
     private final int number;
 
     public Section(int number) {
         super();
         this.number = number;
-        addMarkup(String.format("*Section %d", number), 16, BaseFont.TIMES);
+        addMarkup(String.format("*Section %d", number), 16, List.of(BaseFont.TIMES));
     }
 
     public int getNumber() {
diff --git a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/TextRotationTest.java b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/TextRotationTest.java
index 23cd87f..cc34a44 100644
--- a/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/TextRotationTest.java
+++ b/graphics-pdfbox-layout/src/test/java/org/xbib/graphics/pdfbox/layout/test/TextRotationTest.java
@@ -1,6 +1,8 @@
 package org.xbib.graphics.pdfbox.layout.test;
 
 import java.io.FileOutputStream;
+import java.util.List;
+
 import org.junit.jupiter.api.Test;
 import org.xbib.graphics.pdfbox.layout.element.Document;
 import org.xbib.graphics.pdfbox.layout.element.Paragraph;
@@ -15,13 +17,13 @@ public class TextRotationTest {
         Paragraph paragraph = new Paragraph();
         paragraph.addMarkup("Hello there, here is text text text text text text text text text text text text text text text text" +
                         " text text text text text text text text text text text",
-                10, BaseFont.HELVETICA);
+                10, List.of(BaseFont.HELVETICA));
         paragraph.setMaxWidth(100);
         document.add(paragraph);
 
         paragraph = new Paragraph();
         paragraph.setRotation(90);
-        paragraph.addMarkup("Hello\u00a0Text\u00a0Rotation", 10, BaseFont.HELVETICA);
+        paragraph.addMarkup("Hello\u00a0Text\u00a0Rotation", 10, List.of(BaseFont.HELVETICA));
         document.add(paragraph);
         document.render().save(new FileOutputStream("build/textrotation.pdf")).close();
     }
diff --git a/graphics-pdfbox-layout/src/test/resources/org/xbib/graphics/pdfbox/layout/test/scripting.json b/graphics-pdfbox-layout/src/test/resources/org/xbib/graphics/pdfbox/layout/test/scripting.json
index cb01f9f..df084c8 100644
--- a/graphics-pdfbox-layout/src/test/resources/org/xbib/graphics/pdfbox/layout/test/scripting.json
+++ b/graphics-pdfbox-layout/src/test/resources/org/xbib/graphics/pdfbox/layout/test/scripting.json
@@ -2,6 +2,10 @@
   "type": "document",
   "margin": "0 0 0 0",
   "author": "Jörg Prante",
+  "font": [
+    "helvetica",
+    "notosans"
+  ],
   "elements": [
     {
       "type": "transform",