Author: tilman
Date: Mon Jul  6 07:19:53 2026
New Revision: 1935925

Log:
PDFBOX-4951: add SMP test, by Volker Kunert

Added:
   
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutSMPTest.java
   (contents, props changed)
   pdfbox/trunk/pdfbox-layout-awt/src/test/resources/pdf/GlyphLayoutSMP.pdf   
(contents, props changed)

Added: 
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/GlyphLayoutSMPTest.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/GlyphLayoutSMPTest.java
  Mon Jul  6 07:19:53 2026        (r1935925)
@@ -0,0 +1,135 @@
+/*
+ * 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.io.IOException;
+import java.net.URISyntaxException;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Examples for Supplementary Multilingual Plane with GlyphLayoutProcessorAwt 
that require a
+ * representation with two characters in Java. This is not a new functionality 
but a regression test
+ * that needs to be checked. (Output is identical with plain PDFBox)
+ *
+ * @author Volker Kunert
+ */
+class GlyphLayoutSMPTest extends TestBase
+{
+    private static final String TEXT_INTRO =
+            "Test of Letters from the Supplementary Multilingual Plane, 
Mathematical Alphanumeric Symbols";
+
+    private static final int[] MATHEMATICAL_CODEPOINTS = new int[]{0x1D504, 
0x1D505, 0x212D, 0x1D507, 0x1D508, 0x1D509,
+            0x1D50A, 0x210C, 0x2111, 0x1D50D, 0x1D50E, 0x1D50F, 0x1D510, 
0x1D511, 0x1D512, 0x1D513, 0x1D514, 0x211C,
+            0x1D516, 0x1D517, 0x1D518, 0x1D519, 0x1D51A, 0x1D51B, 0x1D51C, 
0x2128, 0x0A, 0x1D51E, 0x1D51F, 0x1D520,
+            0x1D521, 0x1D522, 0x1D523, 0x1D524, 0x1D525, 0x1D526, 0x1D527, 
0x1D528, 0x1D529, 0x1D52A, 0x1D52B, 0x1D52C,
+            0x1D52D, 0x1D52E, 0x1D52F, 0x1D530, 0x1D531, 0x1D532, 0x1D533, 
0x1D534, 0x1D535, 0x1D536, 0x1D537,
+            0x0A, 0x0A,
+            0x1D7D8, 0x1D7D9, 0x1D7DA, 0x1D7DB, 0x1D7DC, 0x1D7DD, 0x1D7DE, 
0x1D7DF, 0x1D7E0, 0x1D7E1,
+            0x0A, 0x0A,
+            0x1D49C, 0x212C, 0x1D49E, 0x1D49F, 0x2130, 0x2131, 0x1D4A2, 
0x210B, 0x2110, 0x1D4A5, 0x1D4A6, 0x2112,
+            0x2133, 0x1D4A9, 0x1D4AA, 0x1D4AB, 0x1D4AC, 0x211B, 0x1D4AE, 
0x1D4AF, 0x1D4B0, 0x1D4B1, 0x1D4B2, 0x1D4B3,
+            0x1D4B4, 0x1D4B5,
+            0x0A,
+            0x1D4B6, 0x1D4B7, 0x1D4B8, 0x1D4B9, 0x212F, 0x1D4BB, 0x210A, 
0x1D4BD, 0x1D4BE,
+            0x1D4BF, 0x1D4C0, 0x1D4C1, 0x1D4C2, 0x1D4C3, 0x2134, 0x1D4C5, 
0x1D4C6, 0x1D4C7, 0x1D4C8, 0x1D4C9, 0x1D4CA,
+            0x1D4CB, 0x1D4CC, 0x1D4CD, 0x1D4CE, 0x1D4CF,
+            0x0A, 0x0A};
+
+    private static final String MATHEMATICAL = new 
String(MATHEMATICAL_CODEPOINTS, 0, MATHEMATICAL_CODEPOINTS.length);
+
+    /*
+     * break the text into lines and show them
+     */
+    private float showLines(PDPageContentStream cs, PDType0Font font, float 
fontSize,
+            float x, float y, String s) throws IOException
+    {
+
+        s = s.replaceAll("\t", "    ");
+        String[] lines = s.split("[\n]");
+
+        for (String line : lines)
+        {
+            if (!line.isEmpty())
+            {
+                y = showLine(cs, font, fontSize, x, y, line);
+            }
+        }
+        return y;
+    }
+
+
+    /*
+     * show one line
+     */
+    private float showLine(PDPageContentStream cs, PDType0Font font, float 
fontSize,
+            float x, float y, String text) throws IOException
+    {
+        cs.beginText();
+        cs.newLineAtOffset(x, y);
+
+        cs.setFont(font, fontSize);
+        cs.showText(text);
+        cs.endText();
+
+        float height = font.getBoundingBox().getHeight();
+        y -= height / 1000f * fontSize;
+        return y;
+    }
+
+    @Test
+    void testGlyphLayoutSMP() throws IOException, FontFormatException, 
URISyntaxException
+    {
+        GlyphLayoutProcessorAwt glyphLayoutProcessor = new 
GlyphLayoutProcessorAwt();
+
+        String outputName = "GlyphLayoutSMP.pdf";
+        String outputFilename = "target/" + outputName;
+        String sansFontPath = "/ttf/Arimo-Regular.ttf";
+        String mathFontPath = "/ttf/NotoSansMath-Regular.ttf";
+
+        float fontSize = 12.0f;
+
+        try (PDDocument doc = new PDDocument())
+        {
+            PDType0Font sansFont = createPdType0Font(glyphLayoutProcessor, 
doc, sansFontPath);
+            PDType0Font mathFont = createPdType0Font(glyphLayoutProcessor, 
doc, mathFontPath);
+
+            PDPage blankPage = new PDPage();
+            doc.addPage(blankPage);
+            try (PDPageContentStream cs = new PDPageContentStream(doc, 
doc.getPage(0),
+                    PDPageContentStream.AppendMode.APPEND, true))
+            {
+                cs.setGlyphLayoutProcessor(glyphLayoutProcessor);
+
+                float x = blankPage.getBBox().getLowerLeftX() + fontSize;
+                float y = blankPage.getBBox().getUpperRightY() - fontSize;
+
+                y = showLine(cs, sansFont, fontSize, x, y, TEXT_INTRO);
+                y = showLine(cs, sansFont, fontSize, x, y, "Font used: " + 
mathFont.getName());
+                showLines(cs, mathFont, fontSize, x, y, MATHEMATICAL);
+            }
+            doc.save(outputFilename);
+        }
+        checkRenderIdent(outputName);
+    }
+}

Added: pdfbox/trunk/pdfbox-layout-awt/src/test/resources/pdf/GlyphLayoutSMP.pdf
==============================================================================
Binary file. No diff available.

Reply via email to