update to PDFbox 3.0.0 beta1, fix cmap ttf font bug in two consecutive script engine runs by removing cache from org.xbib.graphics.pdfbox.layout.font.Fonts

This commit is contained in:
Jörg Prante 2023-07-31 16:09:11 +02:00
parent ca317f41ec
commit 134343ba47
31 changed files with 455 additions and 166 deletions

View file

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

View file

@ -4,4 +4,5 @@ module org.xbib.graphics.ghostscript {
requires java.logging;
requires transitive java.desktop;
requires transitive org.apache.pdfbox;
requires transitive org.apache.pdfbox.io;
}

View file

@ -7,7 +7,8 @@ import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
@ -201,7 +202,7 @@ public class PDFRasterizer {
PathMatcher pathMatcher = sourceDir.getFileSystem().getPathMatcher("glob:" + globPattern);
List<PDDocument> coverPageDocs = new ArrayList<>();
try (Stream<Path> files = Files.list(sourceDir);
PDDocument pdDocument = new PDDocument(MemoryUsageSetting.setupTempFileOnly());
PDDocument pdDocument = new PDDocument();
OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(targetFile))) {
pdDocument.setResourceCache(null);
List<Path> entries = files.sorted()
@ -223,7 +224,7 @@ public class PDFRasterizer {
if (path.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".pdf")) {
logger.info("found pdf " + path);
try (InputStream inputStream = Files.newInputStream(path)) {
PDDocument doc = PDDocument.load(inputStream);
PDDocument doc = Loader.loadPDF(inputStream.readAllBytes());
for (int i = 0; i < doc.getNumberOfPages(); i++) {
PDPage page = doc.getPage(i);
PDPage newPage = pdDocument.importPage(page); // shallow copy :(

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.pdfbox.groovy.analyze
import groovy.util.logging.Log
import org.apache.pdfbox.Loader
import org.apache.pdfbox.contentstream.PDFGraphicsStreamEngine
import org.apache.pdfbox.cos.COSName
import org.apache.pdfbox.cos.COSStream
@ -23,7 +24,8 @@ class DocumentAnalyzer {
DocumentAnalyzer(InputStream inputStream) {
inputStream.withCloseable {
PDDocument document = PDDocument.load(inputStream)
byte[] bytes = inputStream.readAllBytes()
PDDocument document = Loader.loadPDF(bytes)
result."author" = document.getDocumentInformation().author
result."creator" = document.getDocumentInformation().creator
result."producer" = document.getDocumentInformation().producer

View file

@ -99,7 +99,7 @@ class PdfDocument implements Closeable {
void setPageNumber(int value) {
this.pageNumber = value
contentStream?.close()
contentStream = new PDPageContentStream(pdDocument, currentPage, true, true)
contentStream = new PDPageContentStream(pdDocument, currentPage, PDPageContentStream.AppendMode.APPEND, true)
toStartPosition()
}

View file

@ -4,27 +4,28 @@ import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.pdmodel.font.PDFont
import org.apache.pdfbox.pdmodel.font.PDType0Font
import org.apache.pdfbox.pdmodel.font.PDType1Font
import org.apache.pdfbox.pdmodel.font.Standard14Fonts
import org.xbib.graphics.pdfbox.groovy.Font
class PdfFont {
private static final DEFAULT_FONT = PDType1Font.HELVETICA
private static final DEFAULT_FONT = new PDType1Font(Standard14Fonts.FontName.HELVETICA)
private static fonts = [
'Times-Roman': [regular: PDType1Font.TIMES_ROMAN,
bold: PDType1Font.TIMES_BOLD,
italic : PDType1Font.TIMES_ITALIC,
boldItalic: PDType1Font.TIMES_BOLD_ITALIC],
'Helvetica' : [regular: PDType1Font.HELVETICA,
bold: PDType1Font.HELVETICA_BOLD,
italic : PDType1Font.HELVETICA_OBLIQUE,
boldItalic: PDType1Font.HELVETICA_BOLD_OBLIQUE],
'Courier' : [regular: PDType1Font.COURIER,
bold: PDType1Font.COURIER_BOLD,
italic : PDType1Font.COURIER_OBLIQUE,
boldItalic: PDType1Font.COURIER_BOLD_OBLIQUE],
'Symbol' : [regular: PDType1Font.SYMBOL],
'Dingbat' : [regular: PDType1Font.ZAPF_DINGBATS]
'Times-Roman': [regular: new PDType1Font(Standard14Fonts.FontName.TIMES_ROMAN),
bold: new PDType1Font(Standard14Fonts.FontName.TIMES_BOLD),
italic : new PDType1Font(Standard14Fonts.FontName.TIMES_ITALIC),
boldItalic: new PDType1Font(Standard14Fonts.FontName.TIMES_BOLD_ITALIC) ],
'Helvetica' : [regular: new PDType1Font(Standard14Fonts.FontName.HELVETICA),
bold: new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD),
italic : new PDType1Font(Standard14Fonts.FontName.HELVETICA_OBLIQUE),
boldItalic: new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD_OBLIQUE) ],
'Courier' : [regular: new PDType1Font(Standard14Fonts.FontName.COURIER),
bold: new PDType1Font(Standard14Fonts.FontName.COURIER_BOLD),
italic : new PDType1Font(Standard14Fonts.FontName.COURIER_OBLIQUE),
boldItalic: new PDType1Font(Standard14Fonts.FontName.COURIER_BOLD_OBLIQUE) ],
'Symbol' : [regular: new PDType1Font(Standard14Fonts.FontName.SYMBOL) ],
'Dingbat' : [regular: new PDType1Font(Standard14Fonts.FontName.ZAPF_DINGBATS) ]
]
static boolean addFont(PDDocument document, String name, InputStream inputStream, boolean bold, boolean italic) {

View file

@ -1,10 +1,13 @@
package org.xbib.graphics.pdfbox.groovy.test
import groovy.util.logging.Log
import org.apache.fontbox.ttf.CmapLookup
import org.apache.fontbox.ttf.CmapSubtable
import org.apache.fontbox.ttf.NamingTable
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.junit.Test
import java.nio.file.Files
@ -28,8 +31,9 @@ class LoadFontTest {
private final Map<String, TrueTypeFont> otf = new HashMap<>()
private void addOpenTypeFont(String name, InputStream inputStream) {
TTFParser ttfParser = new TTFParser(false, true)
TrueTypeFont trueTypeFont = ttfParser.parse(inputStream)
TTFParser ttfParser = new TTFParser(true)
RandomAccessRead read = new RandomAccessReadBuffer(inputStream)
TrueTypeFont trueTypeFont = ttfParser.parse(read)
try {
NamingTable nameTable = trueTypeFont.getNaming()
if (!nameTable) {
@ -51,7 +55,7 @@ class LoadFontTest {
log.warning("Missing 'name' entry for PostScript name in font " + inputStream)
}
}
CmapSubtable cmapSubtable = trueTypeFont.getUnicodeCmap(true)
CmapLookup cmapSubtable = trueTypeFont.getUnicodeCmapLookup(true)
if (!cmapSubtable) {
log.warning('missing cmap table in ' + name)
} else {

View file

@ -5,6 +5,7 @@ import org.apache.pdfbox.pdmodel.PDPage
import org.apache.pdfbox.pdmodel.PDPageContentStream
import org.apache.pdfbox.pdmodel.common.PDRectangle
import org.apache.pdfbox.pdmodel.font.PDType1Font
import org.apache.pdfbox.pdmodel.font.Standard14Fonts
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject
@ -67,7 +68,7 @@ class PdfBoxBarcodeTest {
private static void createText(PDPage page, PDPageContentStream contentStream) {
contentStream.moveTo(32.0f, (page.getBBox().height - 80f) as float)
contentStream.beginText()
contentStream.setFont(PDType1Font.HELVETICA, 12f)
contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA), 12f)
contentStream.showText("Hello World")
contentStream.endText()
contentStream.close()

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.pdfbox.groovy.test
import groovy.xml.XmlParser
import org.apache.pdfbox.Loader
import org.apache.pdfbox.pdmodel.PDDocument
import org.xbib.graphics.pdfbox.groovy.Cell
import org.xbib.graphics.pdfbox.groovy.Document
@ -12,7 +13,7 @@ import org.xbib.graphics.pdfbox.groovy.TextBlock
class PdfDocumentLoader {
static Document load(byte[] data) {
PDDocument pdfDoc = PDDocument.load(new ByteArrayInputStream(data))
PDDocument pdfDoc = Loader.loadPDF(data)
Document document = new Document(element: pdfDoc)
def metaData = new XmlParser().parse(pdfDoc.documentCatalog.metadata.createInputStream())
document.margin.top = metaData.'@marginTop' as Integer

View file

@ -6,14 +6,17 @@ import org.apache.pdfbox.pdmodel.font.PDType1Font;
import java.awt.Color;
import java.io.IOException;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD;
public class Cell<T extends PDPage> {
private float width;
private Float height;
private String text;
private PDFont font = PDType1Font.HELVETICA;
private PDFont fontBold = PDType1Font.HELVETICA_BOLD;
private PDFont font = new PDType1Font(HELVETICA);
private PDFont fontBold = new PDType1Font(HELVETICA_BOLD);
private float fontSize = 8;
private Color fillColor;

View file

@ -13,6 +13,10 @@ import java.util.List;
import java.util.Map;
import java.util.Stack;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_OBLIQUE;
public class Paragraph {
private float width;
@ -74,9 +78,9 @@ public class Paragraph {
this.font = font;
// check if we have different default font for italic and bold text
if (FontUtils.getDefaultfonts().isEmpty()) {
fontBold = PDType1Font.HELVETICA_BOLD;
fontItalic = PDType1Font.HELVETICA_OBLIQUE;
fontBoldItalic = PDType1Font.HELVETICA_BOLD_OBLIQUE;
fontBold = new PDType1Font(HELVETICA_BOLD);
fontItalic = new PDType1Font(HELVETICA_OBLIQUE);
fontBoldItalic = new PDType1Font(HELVETICA_BOLD_OBLIQUE);
} else {
fontBold = FontUtils.getDefaultfonts().get("fontBold");
fontBoldItalic = FontUtils.getDefaultfonts().get("fontBoldItalic");

View file

@ -1,6 +1,5 @@
package org.xbib.graphics.pdfbox.layout.element;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.xbib.graphics.pdfbox.layout.element.render.Layout;
@ -45,17 +44,7 @@ public class Document implements Element, Closeable, RenderListener {
* Creates a Document.
*/
public Document() {
this(PageFormats.A4_PORTRAIT, true);
}
/**
* Creates a Document based on the given page format. By default, a
* {@link VerticalLayout} is used.
*
* @param pageFormat the page format box to use.
*/
public Document(PageFormat pageFormat) {
this(pageFormat, true);
this(PageFormats.A4_PORTRAIT);
}
/**
@ -71,18 +60,17 @@ public class Document implements Element, Closeable, RenderListener {
float marginRight,
float marginTop,
float marginBottom) {
this(marginLeft, marginRight, marginTop, marginBottom, true);
this(PageFormat.builder().margins(marginLeft, marginRight, marginTop, marginBottom).build());
}
public Document(float marginLeft,
float marginRight,
float marginTop,
float marginBottom, boolean memory) {
this(PageFormat.builder().margins(marginLeft, marginRight, marginTop, marginBottom).build(), memory);
}
public Document(PageFormat pageFormat, boolean memory) {
this.pdDocument = new PDDocument(memory ? MemoryUsageSetting.setupMainMemoryOnly() : MemoryUsageSetting.setupTempFileOnly());
/**
* Creates a Document based on the given page format. By default, a
* {@link VerticalLayout} is used.
*
* @param pageFormat the page format box to use.
*/
public Document(PageFormat pageFormat) {
this.pdDocument = new PDDocument();
this.pdDocumentInformation = new PDDocumentInformation();
setPageFormat(pageFormat);
}

View file

@ -2,6 +2,8 @@ package org.xbib.graphics.pdfbox.layout.element;
import org.xbib.graphics.pdfbox.layout.font.Font;
import java.util.Objects;
public class TextElement implements Element {
private final boolean markup;
@ -17,6 +19,8 @@ public class TextElement implements Element {
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");
}
public String getValue() {

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.pdfbox.layout.element.scripting;
import java.io.Closeable;
import java.util.logging.Level;
import org.xbib.graphics.pdfbox.layout.element.scripting.command.Command;
import org.xbib.settings.Settings;
@ -7,7 +8,7 @@ import org.xbib.settings.Settings;
import java.io.IOException;
import java.util.logging.Logger;
public class Engine {
public class Engine implements Closeable {
private static final Logger logger = Logger.getLogger(Engine.class.getName());
@ -73,4 +74,8 @@ public class Engine {
}
}
@Override
public void close() throws IOException {
state.close();
}
}

View file

@ -3,11 +3,12 @@ package org.xbib.graphics.pdfbox.layout.element.scripting;
import org.xbib.graphics.pdfbox.layout.element.Document;
import org.xbib.graphics.pdfbox.layout.element.Element;
import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import java.util.Stack;
import java.util.stream.Collectors;
public class State {
public class State implements Closeable {
private final Stack<Element> elements = new Stack<>();
@ -26,8 +27,26 @@ public class State {
List<Document> list = elements.stream()
.filter(e -> e instanceof Document)
.map(e -> (Document) e)
.collect(Collectors.toList());
.toList();
int size = list.size();
return size == 0 ? null : list.get(size - 1);
}
/**
* Close all documents and free resources.
* @throws IOException if a document can not be closed.
*/
@Override
public void close() throws IOException {
elements.stream()
.filter(e -> e instanceof Document)
.map(e -> (Document) e)
.forEach(d -> {
try {
d.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
}

View file

@ -11,7 +11,6 @@ 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;
import org.xbib.graphics.pdfbox.layout.position.Position;
import org.xbib.graphics.pdfbox.layout.text.TextSequence;
import org.xbib.settings.Settings;
import java.util.Locale;

View file

@ -2,25 +2,34 @@ package org.xbib.graphics.pdfbox.layout.font;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
import java.io.IOException;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_BOLD;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_BOLD_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_BOLD;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_BOLD_ITALIC;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_ITALIC;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_ROMAN;
/**
* In order to easy handling with fonts, this enum bundles the
* plain/italic/bold/bold-italic variants of the three standard font types
* {@link PDType1Font#TIMES_ROMAN Times},{@link PDType1Font#COURIER Courier} and
* {@link PDType1Font#HELVETICA Helveticy}.
* Times, Courier, Helveticy.
*/
public enum BaseFont implements Font {
TIMES(PDType1Font.TIMES_ROMAN, PDType1Font.TIMES_BOLD,
PDType1Font.TIMES_ITALIC, PDType1Font.TIMES_BOLD_ITALIC),
TIMES(new PDType1Font(TIMES_ROMAN), new PDType1Font(TIMES_BOLD),
new PDType1Font(TIMES_ITALIC), new PDType1Font(TIMES_BOLD_ITALIC)),
COURIER(PDType1Font.COURIER, PDType1Font.COURIER_BOLD,
PDType1Font.COURIER_OBLIQUE, PDType1Font.COURIER_BOLD_OBLIQUE),
COURIER(new PDType1Font(Standard14Fonts.FontName.COURIER), new PDType1Font(COURIER_BOLD),
new PDType1Font(COURIER_OBLIQUE), new PDType1Font(COURIER_BOLD_OBLIQUE)),
HELVETICA(PDType1Font.HELVETICA, PDType1Font.HELVETICA_BOLD,
PDType1Font.HELVETICA_OBLIQUE, PDType1Font.HELVETICA_BOLD_OBLIQUE);
HELVETICA(new PDType1Font(Standard14Fonts.FontName.HELVETICA), new PDType1Font(HELVETICA_BOLD),
new PDType1Font(HELVETICA_OBLIQUE), new PDType1Font(HELVETICA_BOLD_OBLIQUE));
private final PDFont plainFont;

View file

@ -2,23 +2,16 @@ package org.xbib.graphics.pdfbox.layout.font;
import org.xbib.graphics.pdfbox.layout.element.Document;
import java.util.HashMap;
import java.util.Map;
public enum Fonts {
HELVETICA,
TIMES,
COURIER,
NOTOSANS;
private final Map<String, Font> map = new HashMap<>();
public Font getFont(Document document) {
return map.computeIfAbsent(name(), name -> {
if ("notosans".equalsIgnoreCase(name())) {
return new NotoSansFont(document);
}
return BaseFont.valueOf(name());
});
if ("notosans".equalsIgnoreCase(name())) {
return new NotoSansFont(document);
}
return BaseFont.valueOf(name());
}
}

View file

@ -5,6 +5,7 @@ import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationHighlight;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.element.Document;
@ -66,8 +67,7 @@ public class CustomAnnotationTest {
.getAnnotationsOfType(HighlightAnnotation.class);
for (HighlightAnnotation highlightAnnotation : HighlightAnnotations) {
// use PDF text markup to implement the highlight
PDAnnotationTextMarkup markup = new PDAnnotationTextMarkup(
PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT);
PDAnnotationTextMarkup markup = new PDAnnotationHighlight();
// use the bounding box of the drawn object to position the
// highlight
PDRectangle bounds = new PDRectangle();

View file

@ -13,11 +13,11 @@ import java.io.FileOutputStream;
public class HelloNotoFontTest {
@Test
public void test() throws Exception {
public void testDocumentOne() throws Exception {
Document document = new Document(PageFormats.A4_PORTRAIT);
Font font = new NotoSansFont(document);
Paragraph paragraph = new Paragraph();
paragraph.add(new Indent(32, SpaceUnit.pt));
Font font = new NotoSansFont(document);
paragraph.addMarkup("Hello Noto Regular\n", 12, font);
paragraph.addMarkup("*Hello Noto Bold*\n", 12, font);
paragraph.addMarkup("_Hello Noto Italic_\n", 12, font);
@ -25,6 +25,31 @@ public class HelloNotoFontTest {
paragraph.addText("Hello Unicode Text: Zwrotki dla Dorotki : arcyksiążę fiołków\n", 12, font);
paragraph.addMarkup("Hello Unicode Markup: _Zwrotki dla Dorotki : arcyksiążę fiołków_\n", 12, font);
document.add(paragraph);
Paragraph anotherParagraph = new Paragraph();
anotherParagraph.add(new Indent(32, SpaceUnit.pt));
anotherParagraph.addMarkup("Hello Noto Regular\n", 12, font);
document.add(anotherParagraph);
document.render().save(new FileOutputStream("build/hellonotofont.pdf")).close();
}
@Test
public void testDocumentTwo() throws Exception {
Document document = new Document(PageFormats.A4_PORTRAIT);
Font font = new NotoSansFont(document);
Paragraph paragraph = new Paragraph();
paragraph.add(new Indent(32, SpaceUnit.pt));
paragraph.addMarkup("Hello Noto Regular 2\n", 12, font);
paragraph.addMarkup("*Hello Noto Bold*\n", 12, font);
paragraph.addMarkup("_Hello Noto Italic_\n", 12, font);
paragraph.addMarkup("*_Hello Noto Bold Italic_*\n", 12, font);
paragraph.addText("Hello Unicode Text: Zwrotki dla Dorotki : arcyksiążę fiołków\n", 12, font);
paragraph.addMarkup("Hello Unicode Markup: _Zwrotki dla Dorotki : arcyksiążę fiołków_\n", 12, font);
document.add(paragraph);
Paragraph anotherParagraph = new Paragraph();
anotherParagraph.add(new Indent(32, SpaceUnit.pt));
anotherParagraph.addMarkup("Hello Noto Regular 2\n", 12, font);
document.add(anotherParagraph);
document.render().save(new FileOutputStream("build/hellonotofont2.pdf")).close();
}
}

View file

@ -10,13 +10,27 @@ import java.io.FileOutputStream;
public class ScriptingTest {
@Test
public void script() throws Exception {
public void scriptOne() throws Exception {
Settings settings = Settings.settingsBuilder()
.loadFromResource("json", getClass().getResourceAsStream("scripting.json"))
.build();
Engine engine = new Engine();
engine.execute(settings);
Document document = engine.getState().getDocument();
document.render().save(new FileOutputStream("build/scripting.pdf")).close();
try (Engine engine = new Engine()) {
engine.execute(settings);
Document document = engine.getState().getDocument();
document.render().save(new FileOutputStream("build/scripting1.pdf")).close();
}
}
@Test
public void scriptTwo() throws Exception {
Settings settings = Settings.settingsBuilder()
.loadFromResource("json", getClass().getResourceAsStream("scripting.json"))
.build();
try (Engine engine = new Engine()) {
engine.execute(settings);
Document document = engine.getState().getDocument();
document.render().save(new FileOutputStream("build/scripting2.pdf")).close();
}
}
}

View file

@ -108,7 +108,7 @@
"elements": [
{
"type": "text",
"value": "Hello World 5",
"value": "Hello World 5 Zwrotki dla Dorotki : arcyksiążę fiołków",
"fontsize": 20,
"font": "notosans"
}

View file

@ -1,6 +1,6 @@
package org.xbib.graphics.pdfbox.print;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.PDFPageable;
@ -86,7 +86,8 @@ public class PrintUtility {
}
public static void print(InputStream inputStream, Printer printer) throws Exception {
PDDocument document = PDDocument.load(inputStream, MemoryUsageSetting.setupTempFileOnly());
byte[] bytes = inputStream.readAllBytes();
PDDocument document = Loader.loadPDF(bytes);
PrinterJob job = PrinterJob.getPrinterJob();
job.setPageable(new PDFPageable(document));
job.setPrintService(printer.getService());

View file

@ -251,15 +251,14 @@ public class PdfBoxGraphics2D extends Graphics2D {
PDRectangle bbox,
PdfBoxGraphics2D parentGfx)
throws IOException {
this(document, createXObject(document, bbox), parentGfx);
this(document, createAppearanceStream(document, bbox), parentGfx);
}
public PdfBoxGraphics2D(PDDocument document,
PDFormXObject xFormObject,
PDAppearanceStream pdAppearanceStream,
PdfBoxGraphics2D parentGfx)
throws IOException {
this(document, xFormObject, new PDPageContentStream(document, xFormObject,
xFormObject.getStream().createOutputStream(COSName.FLATE_DECODE)), parentGfx);
this(document, pdAppearanceStream, new PDPageContentStream(document, pdAppearanceStream, pdAppearanceStream.getStream().createOutputStream(COSName.FLATE_DECODE)), parentGfx);
}
public PdfBoxGraphics2D(PDDocument document,
@ -1152,17 +1151,17 @@ public class PdfBoxGraphics2D extends Graphics2D {
}
private void checkNoCopyActive() {
if (copyList.size() > 0) {
if (!copyList.isEmpty()) {
throw new IllegalStateException("Don't use the main context as long as a copy is active! Child context is missing a .dispose() call\n"
+ gatherDebugCopyInfo(this));
}
}
private static PDFormXObject createXObject(PDDocument document, PDRectangle bbox) {
PDFormXObject xFormObject = new PDAppearanceStream(document);
xFormObject.setResources(new PDResources());
xFormObject.setBBox(bbox);
return xFormObject;
private static PDAppearanceStream createAppearanceStream(PDDocument document, PDRectangle bbox) {
PDAppearanceStream appearanceStream = new PDAppearanceStream(document);
appearanceStream.setResources(new PDResources());
appearanceStream.setBBox(bbox);
return appearanceStream;
}
private static String gatherDebugCopyInfo(PdfBoxGraphics2D gfx) {

View file

@ -1,7 +1,6 @@
package org.xbib.graphics.pdfbox.font;
import org.apache.fontbox.ttf.TrueTypeCollection;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
@ -28,6 +27,21 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_BOLD;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_BOLD_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.SYMBOL;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_BOLD;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_BOLD_ITALIC;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_ITALIC;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_ROMAN;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.ZAPF_DINGBATS;
/**
* Default implementation to draw fonts. You can reuse instances of this class
* within a PDDocument for more then one {@link PdfBoxGraphics2D}.
@ -72,7 +86,7 @@ public class DefaultFontDrawer implements FontDrawer, Closeable {
public void registerFont(String fontName, InputStream fontStream) throws IOException {
File fontFile = File.createTempFile("pdfboxgfx2dfont", ".ttf");
try (FileOutputStream out = new FileOutputStream(fontFile)) {
IOUtils.copy(fontStream, out);
fontStream.transferTo(out);
}
fontFile.deleteOnExit();
tempFiles.add(fontFile);
@ -412,10 +426,10 @@ public class DefaultFontDrawer implements FontDrawer, Closeable {
return chooseMatchingTimes(font);
}
if (fontNameEqualsAnyOf(font, "Symbol")) {
return PDType1Font.SYMBOL;
return new PDType1Font(SYMBOL);
}
if (fontNameEqualsAnyOf(font, "ZapfDingbats", "Dingbats")) {
return PDType1Font.ZAPF_DINGBATS;
return new PDType1Font(ZAPF_DINGBATS);
}
return null;
}
@ -429,18 +443,17 @@ public class DefaultFontDrawer implements FontDrawer, Closeable {
*/
public static PDFont chooseMatchingHelvetica(Font font) {
if ((font.getStyle() & (Font.ITALIC | Font.BOLD)) == (Font.ITALIC | Font.BOLD)) {
return PDType1Font.HELVETICA_BOLD_OBLIQUE;
return new PDType1Font(HELVETICA_BOLD_OBLIQUE);
}
if ((font.getStyle() & Font.ITALIC) == Font.ITALIC) {
return PDType1Font.HELVETICA_OBLIQUE;
return new PDType1Font(HELVETICA_OBLIQUE);
}
if ((font.getStyle() & Font.BOLD) == Font.BOLD) {
return PDType1Font.HELVETICA_BOLD;
return new PDType1Font(HELVETICA_BOLD);
}
return PDType1Font.HELVETICA;
return new PDType1Font(HELVETICA);
}
/**
* Get a PDType1Font.COURIER-variant, which matches the given font
*
@ -450,15 +463,15 @@ public class DefaultFontDrawer implements FontDrawer, Closeable {
*/
public static PDFont chooseMatchingCourier(Font font) {
if ((font.getStyle() & (Font.ITALIC | Font.BOLD)) == (Font.ITALIC | Font.BOLD)) {
return PDType1Font.COURIER_BOLD_OBLIQUE;
return new PDType1Font(COURIER_BOLD_OBLIQUE);
}
if ((font.getStyle() & Font.ITALIC) == Font.ITALIC) {
return PDType1Font.COURIER_OBLIQUE;
return new PDType1Font(COURIER_OBLIQUE);
}
if ((font.getStyle() & Font.BOLD) == Font.BOLD) {
return PDType1Font.COURIER_BOLD;
return new PDType1Font(COURIER_BOLD);
}
return PDType1Font.COURIER;
return new PDType1Font(COURIER);
}
/**
@ -470,15 +483,15 @@ public class DefaultFontDrawer implements FontDrawer, Closeable {
*/
public static PDFont chooseMatchingTimes(Font font) {
if ((font.getStyle() & (Font.ITALIC | Font.BOLD)) == (Font.ITALIC | Font.BOLD)) {
return PDType1Font.TIMES_BOLD_ITALIC;
return new PDType1Font(TIMES_BOLD_ITALIC);
}
if ((font.getStyle() & Font.ITALIC) == Font.ITALIC) {
return PDType1Font.TIMES_ITALIC;
return new PDType1Font(TIMES_ITALIC);
}
if ((font.getStyle() & Font.BOLD) == Font.BOLD) {
return PDType1Font.TIMES_BOLD;
return new PDType1Font(TIMES_BOLD);
}
return PDType1Font.TIMES_ROMAN;
return new PDType1Font(TIMES_ROMAN);
}
public static boolean fontNameEqualsAnyOf(Font font, String... names) {

View file

@ -7,7 +7,6 @@ import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.multipdf.PDFCloneUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDResources;

View file

@ -0,0 +1,201 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xbib.graphics.pdfbox.paint;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSObject;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.common.COSObjectable;
/**
* Copied from org.apache.pdfbox.multipdf.util
*/
public class PDFCloneUtility {
private final PDDocument destination;
private final Map<COSBase, COSBase> clonedVersion = new HashMap<>();
private final Set<COSBase> clonedValues = new HashSet<>();
/**
* Creates a new instance for the given target document.
*
* @param dest the destination PDF document that will receive the clones
*/
PDFCloneUtility(PDDocument dest) {
this.destination = dest;
}
/**
* Returns the destination PDF document this cloner instance is set up for.
*
* @return the destination PDF document
*/
PDDocument getDestination() {
return this.destination;
}
/**
* Deep-clones the given object for inclusion into a different PDF document identified by the destination parameter.
* <p>
* Expert use only, dont use it if you dont know exactly what you are doing.
*
* @param base the initial object as the root of the deep-clone operation
* @return the cloned instance of the base object
* @throws IOException if an I/O error occurs
*/
@SuppressWarnings("unchecked")
public <TCOSBase extends COSBase> TCOSBase cloneForNewDocument(TCOSBase base) throws IOException {
if (base == null) {
return null;
}
COSBase retval = clonedVersion.get(base);
if (retval != null) {
// we are done, it has already been converted.
return (TCOSBase) retval;
}
if (clonedValues.contains(base)) {
// Don't clone a clone
return base;
}
retval = cloneCOSBaseForNewDocument(base);
clonedVersion.put(base, retval);
clonedValues.add(retval);
return (TCOSBase) retval;
}
COSBase cloneCOSBaseForNewDocument(COSBase base) throws IOException {
if (base instanceof COSObject) {
return cloneForNewDocument(((COSObject) base).getObject());
}
if (base instanceof COSArray) {
return cloneCOSArray((COSArray) base);
}
if (base instanceof COSStream) {
return cloneCOSStream((COSStream) base);
}
if (base instanceof COSDictionary) {
return cloneCOSDictionary((COSDictionary) base);
}
return base;
}
private COSArray cloneCOSArray(COSArray array) throws IOException {
COSArray newArray = new COSArray();
for (int i = 0; i < array.size(); i++) {
COSBase value = array.get(i);
if (hasSelfReference(array, value)) {
newArray.add(newArray);
} else {
newArray.add(cloneForNewDocument(value));
}
}
return newArray;
}
private COSStream cloneCOSStream(COSStream stream) throws IOException {
COSStream newStream = destination.getDocument().createCOSStream();
try (OutputStream output = newStream.createRawOutputStream();
InputStream input = stream.createRawInputStream()) {
input.transferTo(output);
}
clonedVersion.put(stream, newStream);
for (Map.Entry<COSName, COSBase> entry : stream.entrySet()) {
COSBase value = entry.getValue();
if (hasSelfReference(stream, value)) {
newStream.setItem(entry.getKey(), newStream);
} else {
newStream.setItem(entry.getKey(), cloneForNewDocument(value));
}
}
return newStream;
}
private COSDictionary cloneCOSDictionary(COSDictionary dictionary) throws IOException {
COSDictionary newDictionary = new COSDictionary();
clonedVersion.put(dictionary, newDictionary);
for (Map.Entry<COSName, COSBase> entry : dictionary.entrySet()) {
COSBase value = entry.getValue();
if (hasSelfReference(dictionary, value)) {
newDictionary.setItem(entry.getKey(), newDictionary);
} else {
newDictionary.setItem(entry.getKey(), cloneForNewDocument(value));
}
}
return newDictionary;
}
/**
* Merges two objects of the same type by deep-cloning its members. <br>
* Base and target must be instances of the same class.
*
* @param base the base object to be cloned
* @param target the merge target
* @throws IOException if an I/O error occurs
*/
void cloneMerge(final COSObjectable base, COSObjectable target) throws IOException {
if (base == null || base == target) {
return;
}
cloneMergeCOSBase(base.getCOSObject(), target.getCOSObject());
}
private void cloneMergeCOSBase(final COSBase source, final COSBase target) throws IOException {
COSBase sourceBase = source instanceof COSObject ? ((COSObject) source).getObject() : source;
COSBase targetBase = target instanceof COSObject ? ((COSObject) target).getObject() : target;
if (sourceBase instanceof COSArray array && targetBase instanceof COSArray) {
for (int i = 0; i < array.size(); i++) {
((COSArray) targetBase).add(cloneForNewDocument(array.get(i)));
}
} else if (sourceBase instanceof COSDictionary sourceDict && targetBase instanceof COSDictionary targetDict) {
for (Map.Entry<COSName, COSBase> entry : sourceDict.entrySet()) {
COSName key = entry.getKey();
COSBase value = entry.getValue();
if (targetDict.getItem(key) != null) {
cloneMerge(value, targetDict.getItem(key));
} else {
targetDict.setItem(key, cloneForNewDocument(value));
}
}
}
}
/**
* Check whether an element (of an array or a dictionary) points to its parent.
*
* @param parent COSArray or COSDictionary
* @param value an element
*/
private boolean hasSelfReference(COSBase parent, COSBase value) {
if (value instanceof COSObject) {
COSBase actual = ((COSObject) value).getObject();
return actual == parent;
}
return false;
}
}

View file

@ -1,12 +1,25 @@
package org.xbib.graphics.pdfbox.test;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.font.CoreFontDrawer;
import java.awt.Font;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_BOLD;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_BOLD_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.COURIER_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_OBLIQUE;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.SYMBOL;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_BOLD;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_ITALIC;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_BOLD_ITALIC;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.TIMES_ROMAN;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.ZAPF_DINGBATS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
@ -19,51 +32,29 @@ public class FontDrawerTest {
Font anyFontItalic = anyFont.deriveFont(Font.ITALIC);
Font anyFontBoldItalic = anyFont.deriveFont(Font.BOLD | Font.ITALIC);
Assertions.assertEquals(PDType1Font.COURIER,
CoreFontDrawer.chooseMatchingCourier(anyFont));
assertEquals(PDType1Font.COURIER_BOLD,
CoreFontDrawer.chooseMatchingCourier(anyFontBold));
assertEquals(PDType1Font.COURIER_OBLIQUE,
CoreFontDrawer.chooseMatchingCourier(anyFontItalic));
assertEquals(PDType1Font.COURIER_BOLD_OBLIQUE,
CoreFontDrawer.chooseMatchingCourier(anyFontBoldItalic));
assertEquals(PDType1Font.HELVETICA,
CoreFontDrawer.chooseMatchingHelvetica(anyFont));
assertEquals(PDType1Font.HELVETICA_BOLD,
CoreFontDrawer.chooseMatchingHelvetica(anyFontBold));
assertEquals(PDType1Font.HELVETICA_OBLIQUE,
CoreFontDrawer.chooseMatchingHelvetica(anyFontItalic));
assertEquals(PDType1Font.HELVETICA_BOLD_OBLIQUE,
CoreFontDrawer.chooseMatchingHelvetica(anyFontBoldItalic));
assertEquals(PDType1Font.TIMES_ROMAN,
CoreFontDrawer.chooseMatchingTimes(anyFont));
assertEquals(PDType1Font.TIMES_BOLD,
CoreFontDrawer.chooseMatchingTimes(anyFontBold));
assertEquals(PDType1Font.TIMES_ITALIC,
CoreFontDrawer.chooseMatchingTimes(anyFontItalic));
assertEquals(PDType1Font.TIMES_BOLD_ITALIC,
CoreFontDrawer.chooseMatchingTimes(anyFontBoldItalic));
assertEquals(new PDType1Font(COURIER).getName(), CoreFontDrawer.chooseMatchingCourier(anyFont).getName());
assertEquals(new PDType1Font(COURIER_BOLD).getName(), CoreFontDrawer.chooseMatchingCourier(anyFontBold).getName());
assertEquals(new PDType1Font(COURIER_OBLIQUE).getName(), CoreFontDrawer.chooseMatchingCourier(anyFontItalic).getName());
assertEquals(new PDType1Font(COURIER_BOLD_OBLIQUE).getName(), CoreFontDrawer.chooseMatchingCourier(anyFontBoldItalic).getName());
assertEquals(new PDType1Font(HELVETICA).getName(), CoreFontDrawer.chooseMatchingHelvetica(anyFont).getName());
assertEquals(new PDType1Font(HELVETICA_BOLD).getName(), CoreFontDrawer.chooseMatchingHelvetica(anyFontBold).getName());
assertEquals(new PDType1Font(HELVETICA_OBLIQUE).getName(), CoreFontDrawer.chooseMatchingHelvetica(anyFontItalic).getName());
assertEquals(new PDType1Font(HELVETICA_BOLD_OBLIQUE).getName(), CoreFontDrawer.chooseMatchingHelvetica(anyFontBoldItalic).getName());
assertEquals(new PDType1Font(TIMES_ROMAN).getName(), CoreFontDrawer.chooseMatchingTimes(anyFont).getName());
assertEquals(new PDType1Font(TIMES_BOLD).getName(), CoreFontDrawer.chooseMatchingTimes(anyFontBold).getName());
assertEquals(new PDType1Font(TIMES_ITALIC).getName(), CoreFontDrawer.chooseMatchingTimes(anyFontItalic).getName());
assertEquals(new PDType1Font(TIMES_BOLD_ITALIC).getName(), CoreFontDrawer.chooseMatchingTimes(anyFontBoldItalic).getName());
}
@Test
public void testDefaultFontMapping() {
assertEquals(PDType1Font.HELVETICA,
CoreFontDrawer.mapToCoreFonts(Font.decode(Font.DIALOG)));
assertEquals(PDType1Font.HELVETICA,
CoreFontDrawer.mapToCoreFonts(Font.decode(Font.DIALOG_INPUT)));
assertEquals(PDType1Font.HELVETICA,
CoreFontDrawer.mapToCoreFonts(Font.decode("Arial")));
assertEquals(PDType1Font.COURIER,
CoreFontDrawer.mapToCoreFonts(Font.decode(Font.MONOSPACED)));
assertEquals(PDType1Font.TIMES_ROMAN,
CoreFontDrawer.mapToCoreFonts(Font.decode(Font.SERIF)));
assertEquals(PDType1Font.ZAPF_DINGBATS,
CoreFontDrawer.mapToCoreFonts(Font.decode("Dingbats")));
assertEquals(PDType1Font.SYMBOL,
CoreFontDrawer.mapToCoreFonts(Font.decode("Symbol")));
assertEquals(new PDType1Font(HELVETICA).getName(), CoreFontDrawer.mapToCoreFonts(Font.decode(Font.DIALOG)).getName());
assertEquals(new PDType1Font(HELVETICA).getName(), CoreFontDrawer.mapToCoreFonts(Font.decode(Font.DIALOG_INPUT)).getName());
assertEquals(new PDType1Font(HELVETICA).getName(), CoreFontDrawer.mapToCoreFonts(Font.decode("Arial")).getName());
assertEquals(new PDType1Font(COURIER).getName(), CoreFontDrawer.mapToCoreFonts(Font.decode(Font.MONOSPACED)).getName());
assertEquals(new PDType1Font(TIMES_ROMAN).getName(), CoreFontDrawer.mapToCoreFonts(Font.decode(Font.SERIF)).getName());
assertEquals(new PDType1Font(ZAPF_DINGBATS).getName(), CoreFontDrawer.mapToCoreFonts(Font.decode("Dingbats")).getName());
assertEquals(new PDType1Font(SYMBOL).getName(), CoreFontDrawer.mapToCoreFonts(Font.decode("Symbol")).getName());
assertNull(CoreFontDrawer.mapToCoreFonts(Font.decode("Georgia")));
}
}

View file

@ -20,6 +20,9 @@ import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA;
import static org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName.HELVETICA_BOLD;
class PdfBoxGraphics2DTestBase {
enum Mode {
@ -29,7 +32,7 @@ class PdfBoxGraphics2DTestBase {
void exportGraphic(String dir, String name, GraphicsExporter exporter) {
try {
PDDocument document = new PDDocument();
PDFont helvetica = PDType1Font.HELVETICA;
PDFont helvetica = new PDType1Font(HELVETICA);
File parentDir = new File("build/test/" + dir);
parentDir.mkdirs();
BufferedImage image = new BufferedImage(400, 400, BufferedImage.TYPE_4BYTE_ABGR);
@ -45,7 +48,7 @@ class PdfBoxGraphics2DTestBase {
contentStream.beginText();
contentStream.setStrokingColor(0f, 0f, 0f);
contentStream.setNonStrokingColor(0f, 0f, 0f);
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 15);
contentStream.setFont(new PDType1Font(HELVETICA_BOLD), 15);
contentStream.setTextMatrix(Matrix.getTranslateInstance(10, 800));
contentStream.showText("Mode " + m);
contentStream.endText();

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.pdfbox.test;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
@ -29,6 +30,7 @@ import java.awt.Stroke;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class PdfRerenderTest {
@ -55,7 +57,9 @@ public class PdfRerenderTest {
File parentDir = new File("build/test");
parentDir.mkdirs();
PDDocument document = new PDDocument();
PDDocument sourceDoc = PDDocument.load(PdfRerenderTest.class.getResourceAsStream(name));
InputStream inputStream = PdfRerenderTest.class.getResourceAsStream(name);
byte[] bytes = inputStream.readAllBytes();
PDDocument sourceDoc = Loader.loadPDF(bytes);
for (PDPage sourcePage : sourceDoc.getPages()) {
PDRectangle mediaBox = sourcePage.getMediaBox();
@ -87,7 +91,9 @@ public class PdfRerenderTest {
parentDir.mkdirs();
PDDocument document = new PDDocument();
PDDocument sourceDoc = PDDocument.load(PdfRerenderTest.class.getResourceAsStream(name));
InputStream inputStream = PdfRerenderTest.class.getResourceAsStream(name);
byte[] bytes = inputStream.readAllBytes();
PDDocument sourceDoc = Loader.loadPDF(bytes);
for (PDPage sourcePage : sourceDoc.getPages()) {
PDPage rerenderedPage = new PDPage(sourcePage.getMediaBox());
@ -113,7 +119,9 @@ public class PdfRerenderTest {
parentDir.mkdirs();
PDDocument document = new PDDocument();
PDDocument sourceDoc = PDDocument.load(PdfRerenderTest.class.getResourceAsStream(name));
InputStream inputStream = PdfRerenderTest.class.getResourceAsStream(name);
byte[] bytes = inputStream.readAllBytes();
PDDocument sourceDoc = Loader.loadPDF(bytes);
for (PDPage sourcePage : sourceDoc.getPages()) {
PDPage rerenderedPage = new PDPage(sourcePage.getMediaBox());

View file

@ -39,7 +39,7 @@ dependencyResolutionManagement {
library('bytebuddy', 'net.bytebuddy', 'byte-buddy').version('1.14.4')
library('objenesis', 'org.objenesis', 'objenesis').version('2.6')
library('jna', 'net.java.dev.jna', 'jna').version('5.13.0')
library('pdfbox', 'org.apache.pdfbox', 'pdfbox').version('2.0.28')
library('pdfbox', 'org.apache.pdfbox', 'pdfbox').version('3.0.0-beta1')
library('zxing', 'com.google.zxing', 'javase').version('3.4.1')
library('reflections', 'org.reflections', 'reflections').version('0.9.11')
library('jfreechart', 'org.jfree', 'jfreechart').version('1.5.2')