Author: tilman
Date: Sun Jul 5 09:06:59 2026
New Revision: 1935904
Log:
PDFBOX-4951: add rendering test, refactor
Added:
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/TestBase.java
(contents, props changed)
Modified:
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutBidiTest.java
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutDin91379FormTest.java
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutDin91379Test.java
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutLigaturesAndKerningTest.java
Modified:
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutBidiTest.java
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutBidiTest.java
Sun Jul 5 08:30:13 2026 (r1935903)
+++
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutBidiTest.java
Sun Jul 5 09:06:59 2026 (r1935904)
@@ -19,13 +19,9 @@ package org.apache.pdfbox.glyphlayout;
import org.junit.jupiter.api.Test;
import java.awt.FontFormatException;
-import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
+import java.net.URISyntaxException;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
@@ -36,7 +32,7 @@ import org.apache.pdfbox.pdmodel.font.PD
*
* @author Volker Kunert
*/
-public class GlyphLayoutBidiTest
+public class GlyphLayoutBidiTest extends TestBase
{
public static final String TEXT1 = "نحن الآن في شهر رمضان 1447 هجري";
public static final String TEXT2 = "Guten Tag ";
@@ -78,11 +74,12 @@ public class GlyphLayoutBidiTest
}
@Test
- void testGlyphLayoutBidi() throws IOException, FontFormatException
+ void testGlyphLayoutBidi() throws IOException, FontFormatException,
URISyntaxException
{
GlyphLayoutProcessorAwt glyphLayoutProcessorAwt = new
GlyphLayoutProcessorAwt();
- String outputFilename = "target/GlyphLayoutBidi.pdf";
+ String outputName = "GlyphLayoutBidi.pdf";
+ String outputFilename = "target/" + outputName;
String arabicPath = "/ttf/NotoSansArabic-Regular.ttf";
String lgcPath = "/ttf/DejaVuSans.ttf";
@@ -107,20 +104,6 @@ public class GlyphLayoutBidiTest
}
doc.save(outputFilename);
}
- //TODO add rendering comparison
- try (PDDocument doc = Loader.loadPDF(new File(outputFilename)))
- {
- assertEquals(1, doc.getNumberOfPages());
- }
- }
-
- /*
- * Create the PDType0Font font
- */
- private PDType0Font createPdType0Font(GlyphLayoutProcessorAwt
glyphLayoutProcessorAwt, PDDocument doc,
- String fontPath) throws IOException, FontFormatException
- {
- InputStream fontStream = this.getClass().getResourceAsStream(fontPath);
- return glyphLayoutProcessorAwt.loadFont(doc, fontStream);
+ checkRenderIdent(outputName);
}
}
Modified:
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutDin91379FormTest.java
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutDin91379FormTest.java
Sun Jul 5 08:30:13 2026 (r1935903)
+++
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutDin91379FormTest.java
Sun Jul 5 09:06:59 2026 (r1935904)
@@ -29,7 +29,6 @@ import org.apache.pdfbox.pdmodel.font.PD
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextField;
-import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/*
@@ -42,7 +41,7 @@ import org.junit.jupiter.api.Test;
* @author Volker Kunert
*/
-class GlyphLayoutDin91379FormTest
+class GlyphLayoutDin91379FormTest extends TestBase
{
static String LATIN_CHARS_DIN_91379 =
"DIN 91379: Characters in Unicode for the electronic
processing of names "
@@ -91,7 +90,8 @@ class GlyphLayoutDin91379FormTest
{
GlyphLayoutProcessorAwt glyphLayoutProcessor = new
GlyphLayoutProcessorAwt();
- String outputFilename = "target/GlyphLayoutDIN91379Form.pdf";
+ String outputName = "GlyphLayoutDIN91379Form.pdf";
+ String outputFilename = "target/" + outputName;
String fontSizeString = "12";
@@ -127,11 +127,6 @@ class GlyphLayoutDin91379FormTest
acroForm.flatten();
doc.save(outputFilename);
}
-
- //TODO add rendering comparison
- try (PDDocument doc = Loader.loadPDF(new File(outputFilename)))
- {
- assertEquals(1, doc.getNumberOfPages());
- }
+ checkRenderIdent(outputName);
}
}
Modified:
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutDin91379Test.java
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutDin91379Test.java
Sun Jul 5 08:30:13 2026 (r1935903)
+++
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutDin91379Test.java
Sun Jul 5 09:06:59 2026 (r1935904)
@@ -25,6 +25,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
+import java.net.URISyntaxException;
import org.apache.pdfbox.Loader;
import org.junit.jupiter.api.Test;
@@ -44,7 +45,7 @@ import static org.junit.jupiter.api.Asse
*
* @author Volker Kunert
*/
-class GlyphLayoutDin91379Test
+class GlyphLayoutDin91379Test extends TestBase
{
static String LATIN_CHARS_DIN_91379 =
"DIN 91379: Characters in Unicode for the electronic
processing of names \n"
@@ -91,11 +92,12 @@ class GlyphLayoutDin91379Test
+ "Additional non-letters (not included in DIN 91379): – —
•�";
@Test
- void testGlyphLayoutDin91379() throws IOException, FontFormatException
+ void testGlyphLayoutDin91379() throws IOException, FontFormatException,
URISyntaxException
{
GlyphLayoutProcessorAwt glyphLayoutProcessor = new
GlyphLayoutProcessorAwt();
- String outputPDFFilename = "target/GlyphLayoutDIN91379.pdf";
+ String outputName = "GlyphLayoutDIN91379.pdf";
+ String outputPDFFilename = "target/" + outputName;
String outputTextFilename = "target/GlyphLayoutDIN91379.txt";
float fontSize = 12.0f;
@@ -117,8 +119,8 @@ class GlyphLayoutDin91379Test
}
doc.save(outputPDFFilename);
}
+ checkRenderIdent(outputName);
- //TODO add rendering comparison
try (PDDocument doc = Loader.loadPDF(new File(outputPDFFilename)))
{
assertEquals(1, doc.getNumberOfPages());
@@ -160,17 +162,4 @@ class GlyphLayoutDin91379Test
}
}
}
-
- /*
- * show one line
- */
- private void showCompositesLine(PDPageContentStream cs, PDType0Font font,
float fontSize,
- float x, float y, String line) throws IOException
- {
- cs.beginText();
- cs.setFont(font, fontSize);
- cs.newLineAtOffset(x, y);
- cs.showText(line);
- cs.endText();
- }
}
Modified:
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutLigaturesAndKerningTest.java
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutLigaturesAndKerningTest.java
Sun Jul 5 08:30:13 2026 (r1935903)
+++
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutLigaturesAndKerningTest.java
Sun Jul 5 09:06:59 2026 (r1935904)
@@ -28,10 +28,8 @@ package org.apache.pdfbox.glyphlayout;
*/
import java.awt.FontFormatException;
-import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
-import org.apache.pdfbox.Loader;
+import java.net.URISyntaxException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -42,7 +40,7 @@ import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
-class GlyphLayoutLigaturesAndKerningTest
+class GlyphLayoutLigaturesAndKerningTest extends TestBase
{
static final String FIRACODE_STRING = "!= == === >= <=";
static final String DEJAVU_STRING = "AVATAR, effective, affiliation,
float, film, affluent";
@@ -67,27 +65,31 @@ class GlyphLayoutLigaturesAndKerningTest
try (PDDocument doc = new PDDocument())
{
- PDType0Font lohitBengaliFont =
createPdType0Font(glyphLayoutProcessor, doc, lohitBengaliPath);
+ PDType0Font lohitBengaliFont =
createPdType0Font(glyphLayoutProcessor, doc, lohitBengaliPath,
+ new GlyphLayoutFontLoaderAwt.FontOptions());
PDPage page = new PDPage();
doc.addPage(page);
try (PDPageContentStream cs = new PDPageContentStream(doc, page))
{
cs.setGlyphLayoutProcessor(glyphLayoutProcessor);
-
+
IllegalArgumentException ex =
assertThrows(IllegalArgumentException.class, () ->
showComposites(cs, lohitBengaliFont, 1, 0, 0,
"123ABC"));
assertEquals("Missing glyph in font 'Lohit Bengali' for the
character 'A', codePoint: 65 (U+0041).", ex.getMessage());
+
+ // Ignore the "You did not call endText()" warning, this is
because of the premature close
}
}
}
@Test
- void testLigaturesAndKerning() throws IOException, FontFormatException
+ void testLigaturesAndKerning() throws IOException, FontFormatException,
URISyntaxException
{
GlyphLayoutProcessorAwt glyphLayoutProcessor = new
GlyphLayoutProcessorAwt();
- String outputFilename = "target/GlyphLayoutLigaturesAndKerning.pdf";
+ String outputName = "GlyphLayoutLigaturesAndKerning.pdf";
+ String outputFilename = "target/" + outputName;
String firaPath = "/ttf/FiraCode-Regular.ttf";
String dejavuPath = "/ttf/DejaVuSans.ttf"; // ligatures not in
Liberation nor in Arimo
String lohitBengaliPath = "/ttf/Lohit-Bengali.ttf";
@@ -133,39 +135,13 @@ class GlyphLayoutLigaturesAndKerningTest
}
doc.save(outputFilename);
}
- //TODO add rendering comparison
- try (PDDocument doc = Loader.loadPDF(new File(outputFilename)))
- {
- assertEquals(1, doc.getNumberOfPages());
- }
- }
-
- /*
- * Create the PDType0Font font
- */
- private PDType0Font createPdType0Font(GlyphLayoutProcessorAwt
glyphLayoutProcessor, PDDocument pdDocument,
- String fontPath) throws IOException, FontFormatException
- {
- InputStream fontStream = this.getClass().
- getResourceAsStream(fontPath);
- return glyphLayoutProcessor.loadFont(pdDocument, fontStream);
+ checkRenderIdent(outputName);
}
- /*
- * Create the PDType0Font font with font options
- */
- private PDType0Font createPdType0Font(GlyphLayoutProcessorAwt
glyphLayoutProcessor, PDDocument pdDocument,
- String fontPath, GlyphLayoutFontLoaderAwt.FontOptions fontOptions)
throws IOException, FontFormatException
- {
- InputStream fontStream = this.getClass().
- getResourceAsStream(fontPath);
- return glyphLayoutProcessor.loadFont(pdDocument, fontStream,
fontOptions);
- }
-
- /*
+ /**
* break the text into lines and show them
*/
- public static float showComposites(PDPageContentStream cs, PDType0Font
font, float fontSize,
+ private float showComposites(PDPageContentStream cs, PDType0Font font,
float fontSize,
float x, float y, String s) throws IOException
{
@@ -184,17 +160,4 @@ class GlyphLayoutLigaturesAndKerningTest
}
return y;
}
-
- /*
- * show one line
- */
- public static void showCompositesLine(PDPageContentStream cs, PDType0Font
font, float fontSize,
- float x, float y, String line) throws IOException
- {
- cs.beginText();
- cs.setFont(font, fontSize);
- cs.newLineAtOffset(x, y);
- cs.showText(line);
- cs.endText();
- }
}
Added:
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/TestBase.java
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/TestBase.java
Sun Jul 5 09:06:59 2026 (r1935904)
@@ -0,0 +1,108 @@
+/*
+ * 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.apache.pdfbox.glyphlayout;
+
+import java.awt.FontFormatException;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import org.apache.pdfbox.Loader;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ *
+ * @author Tilman Hausherr
+ * @author Volker Kunert
+ */
+class TestBase
+{
+ void checkRenderIdent(String outputName) throws IOException,
URISyntaxException
+ {
+ BufferedImage expectedImage;
+ BufferedImage actualImage;
+ try (PDDocument doc = Loader.loadPDF(new File("target/" + outputName)))
+ {
+ PDFRenderer r = new PDFRenderer(doc);
+ expectedImage = r.renderImage(0);
+ }
+ try (PDDocument doc = Loader.loadPDF(new
File(TestBase.class.getResource("/pdf/" + outputName).toURI())))
+ {
+ PDFRenderer r = new PDFRenderer(doc);
+ actualImage = r.renderImage(0);
+ }
+
+ int w = expectedImage.getWidth();
+ int h = expectedImage.getHeight();
+ assertEquals(w, actualImage.getWidth());
+ assertEquals(h, actualImage.getHeight());
+ for (int y = 0; y < h; ++y)
+ {
+ for (int x = 0; x < w; ++x)
+ {
+ int p1 = expectedImage.getRGB(x, y);
+ int p2 = actualImage.getRGB(x, y);
+ if (p1 != p2)
+ {
+ String errMsg = String.format("(%d,%d) expected: <%08X>
but was: <%08X>; ",
+ x, y, p1, p2);
+ fail(errMsg);
+ }
+ }
+ }
+ }
+
+ /**
+ * Create the PDType0Font font
+ */
+ PDType0Font createPdType0Font(GlyphLayoutProcessorAwt
glyphLayoutProcessor, PDDocument doc,
+ String fontPath) throws IOException, FontFormatException
+ {
+ return createPdType0Font(glyphLayoutProcessor, doc, fontPath, new
GlyphLayoutFontLoaderAwt.FontOptions());
+ }
+
+ /*
+ * Create the PDType0Font font with font options
+ */
+ PDType0Font createPdType0Font(GlyphLayoutProcessorAwt
glyphLayoutProcessor, PDDocument doc,
+ String fontPath, GlyphLayoutFontLoaderAwt.FontOptions fontOptions)
throws IOException, FontFormatException
+ {
+ try (InputStream fontStream =
this.getClass().getResourceAsStream(fontPath))
+ {
+ return glyphLayoutProcessor.loadFont(doc, fontStream, fontOptions);
+ }
+ }
+
+ /*
+ * show one line
+ */
+ void showCompositesLine(PDPageContentStream cs, PDType0Font font, float
fontSize,
+ float x, float y, String line) throws IOException
+ {
+ cs.beginText();
+ cs.setFont(font, fontSize);
+ cs.newLineAtOffset(x, y);
+ cs.showText(line);
+ cs.endText();
+ }
+}