Author: tilman
Date: Thu Jul 30 08:33:24 2026
New Revision: 1936716
Log:
PDFBOX-4951: add FOP based glyph layout, by Volker Kunert
Added:
pdfbox/trunk/pdfbox-layout-fop/ (props changed)
pdfbox/trunk/pdfbox-layout-fop/pom.xml (contents, props changed)
pdfbox/trunk/pdfbox-layout-fop/src/
pdfbox/trunk/pdfbox-layout-fop/src/main/
pdfbox/trunk/pdfbox-layout-fop/src/main/java/
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/examples/
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/examples/GlyphLayoutHelloWorldFOP.java
- copied, changed from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/main/java/org/apache/pdfbox/glyphlayout/examples/GlyphLayoutHelloWorldAWT.java
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/fop/
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/fop/FopStringTextFragment.java
(contents, props changed)
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutFontLoaderFop.java
(contents, props changed)
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutProcessorFop.java
(contents, props changed)
pdfbox/trunk/pdfbox-layout-fop/src/test/
pdfbox/trunk/pdfbox-layout-fop/src/test/appended-resources/
pdfbox/trunk/pdfbox-layout-fop/src/test/appended-resources/META-INF/
pdfbox/trunk/pdfbox-layout-fop/src/test/appended-resources/META-INF/LICENSE
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/appended-resources/META-INF/LICENSE
pdfbox/trunk/pdfbox-layout-fop/src/test/java/
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutBidiTest.java
- copied, changed from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutBidiTest.java
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutDin91379FormTest.java
- copied, changed from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutDin91379FormTest.java
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutDin91379Test.java
- copied, changed from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutDin91379Test.java
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutHelloWorldTest.java
- copied, changed from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutHelloWorldAWTTest.java
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutLigaturesAndKerningTest.java
- copied, changed from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutLigaturesAndKerningTest.java
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutSMPTest.java
- copied, changed from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutSMPTest.java
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/TestBase.java
- copied, changed from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/TestBase.java
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/log4j2.xml
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/log4j2.xml
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/GlyphLayoutBidi.pdf
(contents, props changed)
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/GlyphLayoutDIN91379.pdf
(contents, props changed)
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/GlyphLayoutDIN91379Form.pdf
(contents, props changed)
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/GlyphLayoutLigaturesAndKerning.pdf
(contents, props changed)
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/GlyphLayoutSMP.pdf
(contents, props changed)
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/HelloWorld.pdf
- copied, changed from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/pdf/HelloWorld.pdf
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/PdfForm.pdf
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/pdf/PdfForm.pdf
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/Arimo-Regular.ttf
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/Arimo-Regular.ttf
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/DejaVuSans.ttf
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/DejaVuSans.ttf
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/FiraCode-Regular.ttf
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/FiraCode-Regular.ttf
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/Lohit-Bengali.ttf
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/Lohit-Bengali.ttf
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/NotoSansArabic-Regular.ttf
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/NotoSansArabic-Regular.ttf
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/NotoSansBengali-Regular.ttf
(contents, props changed)
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/NotoSansMath-Regular.ttf
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/NotoSansMath-Regular.ttf
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/NotoSansThai-Regular.ttf
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/NotoSansThai-Regular.ttf
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/txt/
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/txt/GlyphLayoutDIN91379.txt
- copied unchanged from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/txt/GlyphLayoutDIN91379.txt
Modified:
pdfbox/trunk/pom.xml
Added: pdfbox/trunk/pdfbox-layout-fop/pom.xml
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ pdfbox/trunk/pdfbox-layout-fop/pom.xml Thu Jul 30 08:33:24 2026
(r1936716)
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+! 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.
+!-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.pdfbox</groupId>
+ <artifactId>pdfbox-parent</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>pdfbox-layout-fop</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>Apache PDFBox Layout FOP</name>
+ <description>
+ The Apache PDFBox library is an open source Java tool for working with
PDF documents.
+ This artifact contains classes for script layout with Apache FOP.
+ </description>
+ <inceptionYear>2002</inceptionYear>
+
+ <scm>
+
<connection>scm:svn:https://svn.apache.org/repos/asf/pdfbox/trunk/pdfbox-layout-fop</connection>
+
<developerConnection>scm:svn:https://svn.apache.org/repos/asf/pdfbox/trunk/pdfbox-layout-fop</developerConnection>
+ <url>https://svn.apache.org/viewvc/pdfbox/trunk/pdfbox-layout-fop</url>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.pdfbox</groupId>
+ <artifactId>pdfbox</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.xmlgraphics</groupId>
+ <artifactId>fop</artifactId>
+ <version>2.11</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+
<Automatic-Module-Name>org.apache.pdfbox.pdfbox-layout-fop</Automatic-Module-Name>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <inputExcludes>
+
<inputExclude>src/test/resources/pdf/*.pdf</inputExclude>
+
<inputExclude>src/test/resources/txt/GlyphLayoutDIN91379.txt</inputExclude>
+ </inputExcludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Copied and modified:
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/examples/GlyphLayoutHelloWorldFOP.java
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/main/java/org/apache/pdfbox/glyphlayout/examples/GlyphLayoutHelloWorldAWT.java)
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/main/java/org/apache/pdfbox/glyphlayout/examples/GlyphLayoutHelloWorldAWT.java
Sat Jul 25 14:39:51 2026 (r1936582, copy source)
+++
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/examples/GlyphLayoutHelloWorldFOP.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -16,31 +16,32 @@
*/
package org.apache.pdfbox.glyphlayout.examples;
-import java.awt.FontFormatException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import org.apache.pdfbox.glyphlayout.fop.GlyphLayoutProcessorFop;
-import org.apache.pdfbox.glyphlayout.awt.GlyphLayoutFontLoaderAwt;
-import org.apache.pdfbox.glyphlayout.awt.GlyphLayoutProcessorAwt;
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;
/**
- * Creates a simple document with a TrueType font using GlyphLayoutProcessorAwt
+ * Creates a simple document with a TrueType font using GlyphLayoutProcessorFop
* adapted from org.apache.pdfbox.examples.pdmodel.HelloWorldTTF
+ * <p>
+ * This subproject is an alternative to the AWT subproject; DIN 91379
characters will work, but
+ * complex scripts won't. For most people, the AWT project is the better
choice.
*/
-public class GlyphLayoutHelloWorldAWT
+public class GlyphLayoutHelloWorldFOP
{
- public static void main(String[] args) throws IOException,
FontFormatException
+ public static void main(String[] args) throws IOException
{
- new GlyphLayoutHelloWorldAWT().test(args);
+ new GlyphLayoutHelloWorldFOP().test(args);
}
- public void test(String[] args) throws IOException, FontFormatException
+ public void test(String[] args) throws IOException
{
if (args.length != 3)
{
@@ -57,20 +58,16 @@ public class GlyphLayoutHelloWorldAWT
PDPage page = new PDPage();
doc.addPage(page);
- GlyphLayoutProcessorAwt glyphLayoutProcessorAwt = new
GlyphLayoutProcessorAwt();
+ GlyphLayoutProcessorFop glyphLayoutProcessorFop = new
GlyphLayoutProcessorFop();
PDType0Font font;
- GlyphLayoutFontLoaderAwt.FontOptions fontOptions = new
GlyphLayoutFontLoaderAwt.FontOptions();
- // call fontOptions.setKerningOn() for kerning
- // call fontOptions.setLigaturesOn() for additional ligatures,
e.g. "ffl", "ffi" etc
- // however mandatory replacements (e.g. in Bengali, Thai, Arabic)
are always active
try (InputStream is = new FileInputStream(ttfPath))
{
- font = glyphLayoutProcessorAwt.loadFont(doc, is, fontOptions);
+ font = glyphLayoutProcessorFop.loadFont(doc, is);
}
try (PDPageContentStream contents = new PDPageContentStream(doc,
page))
{
- contents.setGlyphLayoutProcessor(glyphLayoutProcessorAwt);
+ contents.setGlyphLayoutProcessor(glyphLayoutProcessorFop);
contents.beginText();
contents.setFont(font, 20);
contents.newLineAtOffset(100, 700);
Added:
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/fop/FopStringTextFragment.java
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/fop/FopStringTextFragment.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -0,0 +1,84 @@
+package org.apache.pdfbox.glyphlayout.fop;
+
+/*
+ * 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.
+ */
+import org.apache.fop.fonts.TextFragment;
+
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+
+/**
+ * Fop TextFragment created from String
+ */
+public class FopStringTextFragment implements TextFragment
+{
+
+ private final String s;
+
+ public FopStringTextFragment(String s)
+ {
+ this.s = s;
+ }
+
+ @Override
+ public CharacterIterator getIterator()
+ {
+ return new StringCharacterIterator(s);
+ }
+
+ @Override
+ public int getBeginIndex()
+ {
+ return 0;
+ }
+
+ @Override
+ public int getEndIndex()
+ {
+ return s.length() - 1;
+ }
+
+ @Override
+ public String getScript()
+ {
+ return "auto";
+ }
+
+ @Override
+ public String getLanguage()
+ {
+ return "none";
+ }
+
+ @Override
+ public int getBidiLevel()
+ {
+ return 0;
+ }
+
+ @Override
+ public char charAt(int i)
+ {
+ return s.charAt(i);
+ }
+
+ @Override
+ public CharSequence subSequence(int i, int i1)
+ {
+ return s.subSequence(i, i1 + 1);
+ }
+}
Added:
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutFontLoaderFop.java
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutFontLoaderFop.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -0,0 +1,175 @@
+/*
+ * 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.fop;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.apps.io.ResourceResolverFactory;
+import org.apache.fop.fonts.EmbeddingMode;
+import org.apache.fop.fonts.EncodingMode;
+import org.apache.fop.fonts.FontLoader;
+import org.apache.fop.fonts.FontUris;
+import org.apache.fop.fonts.MultiByteFont;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
+import org.apache.xmlgraphics.io.Resource;
+import org.apache.xmlgraphics.io.ResourceResolver;
+
+
+/**
+ * Loads the PDType0Font and awt.Font for GlyphLayoutProcessorAwt
+ * <p>
+ * Use an object of this class only in one thread.
+ *
+ * @author Volker Kunert
+ */
+public class GlyphLayoutFontLoaderFop
+{
+
+ /**
+ * Mapping from PDFBox font to AWT font
+ */
+ private final Map<PDType0Font, MultiByteFont> fopFontMap = new
ConcurrentHashMap<>();
+
+ /**
+ * Loads the AWT font needed for layout
+ *
+ * @param pdDocument document
+ * @param inputStream of the font
+ * @param embedSubset
+ * @return pdType0Font PDFBox font
+ * @throws IOException if font can not be loaded
+ */
+ public PDType0Font loadFont(PDDocument pdDocument, InputStream
inputStream, boolean embedSubset)
+ throws IOException
+ {
+ Objects.requireNonNull(inputStream, "InputStream must not be null");
+ PDType0Font pdType0Font;
+
+ // Copy font stream into memory to read it twice for creation of
PDType0Font and aww.Font
+ try (ByteArrayInputStream bais = new
ByteArrayInputStream(inputStream.readAllBytes()))
+ {
+ pdType0Font = PDType0Font.load(pdDocument, bais, embedSubset);
+ bais.reset();
+ loadFopFont(pdType0Font, bais);
+ }
+ return pdType0Font;
+ }
+
+ /**
+ * Loads the Fop font needed for layout
+ *
+ * @param doc document
+ * @param inputStream of the font
+ * @return pdType0Font PDFBox font
+ * @throws IOException if font can not be loaded
+ */
+ public PDType0Font loadFont(PDDocument doc, InputStream inputStream)
+ throws IOException
+ {
+ return loadFont(doc, inputStream, true);
+ }
+
+ /**
+ * Loads the AWT font needed for layout
+ *
+ * @param pdType0Font PDFBox font
+ * @param inputStream of the font file
+ * @throws IOException if font can not be loaded
+ */
+ protected void loadFopFont(PDType0Font pdType0Font, InputStream
inputStream)
+ throws IOException
+ {
+ if (!fopFontMap.containsKey(pdType0Font))
+ {
+ try
+ {
+ ResourceResolver resourceResolver = new
FopInputStreamResourceResolver(inputStream);
+ InternalResourceResolver internalResourceResolver =
ResourceResolverFactory
+ .createInternalResourceResolver(new
URI(pdType0Font.getName()), resourceResolver);
+ FontUris fontUris = new FontUris(new
URI(pdType0Font.getName()), null);
+ MultiByteFont mbf = (MultiByteFont)
FontLoader.loadFont(fontUris, null, true, EmbeddingMode.AUTO,
+ EncodingMode.AUTO, true, true,
+ internalResourceResolver, false, false, false);
+ Objects.requireNonNull(mbf);
+ fopFontMap.put(pdType0Font, mbf);
+ }
+ catch (URISyntaxException ex)
+ {
+ throw new IOException(ex);
+ }
+ }
+ }
+
+ /**
+ * Determines if glyph layout is supported for this font
+ *
+ * @param font PDFBox font
+ * @return true if glyph layout is supported for this font and this font
is a PDType0Font
+ */
+ public boolean supportsFont(PDFont font)
+ {
+ return fopFontMap.containsKey(font);
+ }
+
+ /**
+ * Gets the corresponding Fop font for the given PDFBox font
+ *
+ * @param font PDFBox font
+ * @return fop font if available
+ */
+ public MultiByteFont getFopFont(PDType0Font font)
+ {
+ return fopFontMap.get(font);
+ }
+
+ /**
+ * Resolver needed to construct a FOP MultibyteFont
+ */
+ static class FopInputStreamResourceResolver implements ResourceResolver
+ {
+ private final InputStream inputStream;
+
+ public FopInputStreamResourceResolver(InputStream inputStream)
+ {
+ this.inputStream = inputStream;
+ }
+
+ @Override
+ public OutputStream getOutputStream(URI arg0) throws IOException
+ {
+ return null;
+ }
+
+ @Override
+ public Resource getResource(URI arg0) throws IOException
+ {
+ return new Resource(inputStream);
+ }
+ }
+}
Added:
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutProcessorFop.java
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++
pdfbox/trunk/pdfbox-layout-fop/src/main/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutProcessorFop.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -0,0 +1,362 @@
+/*
+ * 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.fop;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.Bidi;
+import java.util.Objects;
+import org.apache.fop.fonts.Font;
+
+import org.apache.fop.fonts.GlyphMapping;
+import org.apache.fop.fonts.MultiByteFont;
+import org.apache.fop.traits.MinOptMax;
+
+import org.apache.pdfbox.pdmodel.ContentStreamForGlyphLayoutInterface;
+import org.apache.pdfbox.pdmodel.GlyphLayoutProcessorInterface;
+import org.apache.pdfbox.pdmodel.GlyphsAndPositions;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
+
+
+/**
+ * Processor for glyph layout using Apache FOP
+ * <p>
+ * Use an object of this class only in one thread.
+ *
+ * @author Volker Kunert
+ */
+public class GlyphLayoutProcessorFop implements GlyphLayoutProcessorInterface
+{
+
+ private final GlyphLayoutFontLoaderFop glyphLayoutFontLoaderFop;
+
+ /*
+ Before you call GlyphMapping.doGlyphMapping to position the glyphs,
+ the font size must be multiplied by this factor. Otherwise, the
+ positioning is wrong.
+ */
+ private final float FOP_FONTSIZE_FACTOR = 1e3f;
+
+ /**
+ * Constructs a GlyphLayoutProcessorFop
+ *
+ */
+ public GlyphLayoutProcessorFop()
+ {
+ this.glyphLayoutFontLoaderFop = new GlyphLayoutFontLoaderFop();
+ }
+
+ /**
+ * Checks if glyphs needed for text are missing in t
+ *
+ * @param text text to be checked
+ * @param mbf font to be checked
+ * @throws IllegalArgumentException if glyphs are missing
+ */
+ public static void checkMissingGlyphs(String text, MultiByteFont mbf)
+ {
+ int[] codePoints = text.codePoints().toArray();
+ for (int cp : codePoints)
+ {
+ if (mbf.findGlyphIndex(cp) == 0)
+ {
+ String s = new String(new int[]{cp}, 0, 1);
+ throw new IllegalArgumentException(
+ String.format("Missing glyph in font '%s' for the
character '%s', codePoint: %d (U+%04x).",
+ mbf.getFontName(), s, cp, cp));
+ }
+ }
+ }
+
+ /**
+ * Checks if the font is supported
+ * <p>
+ * This class supports OpenType fonts with description of glyphs as
TrueType outlines, i.e.
+ * *.ttf-files. *.otf-files using CFF outlines are not supported by PDFBox
+ *
+ * @param font to be checked
+ * @return true if glyph layout is supported for this font and this font
is a PDType0Font
+ */
+ @Override
+ public boolean supportsFont(PDFont font)
+ {
+ return glyphLayoutFontLoaderFop.supportsFont(font);
+ }
+
+ /**
+ * Loads the font needed for layout
+ *
+ * @param pdDocument document
+ * @param inputStream of the font
+ * @param embedSubset must be false for PDF forms
+ * @throws IOException if font can not be loaded
+ */
+ public PDType0Font loadFont(PDDocument pdDocument, InputStream
inputStream, boolean embedSubset) throws IOException
+ {
+ return glyphLayoutFontLoaderFop.loadFont(pdDocument, inputStream,
embedSubset);
+ }
+
+ /**
+ * Loads the AWT font needed for layout
+ *
+ * @param pdDocument document
+ * @param inputStream of the font
+ * @throws IOException if font can not be loaded
+ */
+ public PDType0Font loadFont(PDDocument pdDocument, InputStream
inputStream) throws IOException
+ {
+ return glyphLayoutFontLoaderFop.loadFont(pdDocument, inputStream,
true);
+ }
+
+ /**
+ * Computes glyph positioning
+ *
+ * @param font to be used
+ * @param fontSize font size
+ * @param text text to show
+ * @param bidiLevel
+ */
+ protected GlyphMapping computeGlyphAndPositions(PDType0Font font, float
fontSize, String text, int bidiLevel)
+ {
+ Objects.requireNonNull(font, "Font must be set");
+ Objects.requireNonNull(text, "Text must be set");
+
+ MultiByteFont mbf = glyphLayoutFontLoaderFop.getFopFont(font);
+
+ checkMissingGlyphs(text, mbf);
+
+ MinOptMax letterSpaceIPD = MinOptMax.getInstance(0);
+ MinOptMax[] letterSpaceAdjustArray = new MinOptMax[text.length()];
+
+ org.apache.fop.fonts.Font fopFont = new Font(mbf.getFontName(), null,
mbf, (int) (fontSize * FOP_FONTSIZE_FACTOR));
+
+ return GlyphMapping.doGlyphMapping(
+ new FopStringTextFragment(text), 0, text.length() - 1, fopFont,
+ letterSpaceIPD, letterSpaceAdjustArray, ' ',
+ ' ', //?
+ false, bidiLevel, false, true, false);
+ }
+
+ /**
+ * Converts the codepoints of the text to glyph ids
+ *
+ * @param font the font to be used
+ * @param text the text to be converted
+ * @return glyph ids with respect to font
+ */
+ protected int[] convertCharsToGlyphIds(PDType0Font font, String text)
+ {
+ MultiByteFont mbf = glyphLayoutFontLoaderFop.getFopFont(font);
+ return text.codePoints().map(cp -> mbf.findGlyphIndex(cp)).toArray();
+ }
+
+ /**
+ * Shows a text using glyph positioning (if needed)
+ *
+ * @param contentStream the content stream
+ * @param font to be used
+ * @param fontSize font size
+ * @param text text to show
+ * @throws IOException if an I/O exception occurs
+ * @throws IllegalArgumentException if glyphs are missing
+ */
+ @Override
+ public void showText(ContentStreamForGlyphLayoutInterface contentStream,
PDType0Font font, float fontSize, String text) throws IOException
+ {
+ Objects.requireNonNull(text, "Text must be set");
+
+ if (Bidi.requiresBidi(text.toCharArray(), 0, text.length()))
+ {
+ Bidi bidi = new Bidi(text, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+ if (bidi.isMixed())
+ {
+ // Split and Reorder
+ // See PDFTextStripper.handleDirection
+ // collect individual bidi information
+ int runCount = bidi.getRunCount();
+ byte[] levels = new byte[runCount];
+ Integer[] runs = new Integer[runCount];
+
+ for (int i = 0; i < runCount; i++)
+ {
+ levels[i] = (byte) bidi.getRunLevel(i);
+ runs[i] = i;
+ }
+ // reorder individual parts based on their levels
+ Bidi.reorderVisually(levels, 0, runs, 0, runCount);
+
+ for (int i = 0; i < runCount; i++)
+ {
+ int index = runs[i];
+ int start = bidi.getRunStart(index);
+ int limit = bidi.getRunLimit(index);
+ int bidiLevel = levels[index];
+
+ // Map to correct value for GlyphMapping.doGlyphMapping
+ // 0 LTR equal in java.text.Bidi and
org.apache.fop.traits.Direction
+ // 1 RTL equal in java.text.Bidi and
org.apache.fop.traits.Direction
+ bidiLevel = bidiLevel % 2; // even LTR, odd RTL
+ String part = text.substring(start, limit);
+ showTextUni(contentStream, font, fontSize, part,
bidiLevel);
+ }
+ }
+ else
+ {
+ showTextUni(contentStream, font, fontSize, text,
bidi.getBaseLevel());
+ }
+ }
+ else
+ {
+ showTextUni(contentStream, font, fontSize, text,
Bidi.DIRECTION_LEFT_TO_RIGHT);
+ }
+ }
+
+ /**
+ * Shows a text using FOP positioning
+ *
+ * @param contentStream
+ * @param font
+ * @param text the text to show
+ * @param fontSize
+ * @param bidiLevel
+ * @throws IOException if an I/O error occurs
+ */
+ protected void showTextUni(ContentStreamForGlyphLayoutInterface
contentStream, PDType0Font font, float fontSize,
+ String text, int bidiLevel) throws IOException
+ {
+
+ Objects.requireNonNull(text, "Text must be set");
+ Objects.requireNonNull(contentStream, "contentStream must be set");
+
+ GlyphMapping glyphMapping = computeGlyphAndPositions(font, fontSize,
text, bidiLevel);
+
+ text = glyphMapping.mapping == null ? text : glyphMapping.mapping;
+
+ int[][] gpa = glyphMapping.gposAdjustments != null ?
glyphMapping.gposAdjustments : createZeroGpa(text.length());
+
+ if (bidiLevel == Bidi.DIRECTION_RIGHT_TO_LEFT)
+ {
+ gpa = reverseGpa(gpa);
+ text = new StringBuilder(text).reverse().toString();
+ }
+ int[] glyphIds = convertCharsToGlyphIds(font, text);
+
+ if (glyphIds.length != text.length())
+ {
+ if (glyphMapping.gposAdjustments == null)
+ {
+ gpa = createZeroGpa(glyphIds.length);
+ }
+ else
+ {
+ // This case:
+ // letters from the supplementary multilingual plane AND
position adjustments
+ // is not implemented
+ throw new IllegalStateException("glyphIds.length !=
text.length() and gposAdjustments!=null"
+ + glyphIds.length + " " + text.length() + " " + text);
+ }
+ }
+
+ final float delta = Math.ulp(fontSize); // do only adjustments bigger
than or equal to one ulp of the font size
+ GlyphsAndPositions ga = new GlyphsAndPositions();
+
+ for (int i = 0; i < glyphIds.length; i++)
+ {
+ // 4-tuples of placement [PX,PY] and advance [AX,AY] adjustments,
in that order,
+ float px = gpa[i][0] / fontSize * 1000f / FOP_FONTSIZE_FACTOR;
+ float py = gpa[i][1] / FOP_FONTSIZE_FACTOR;
+ float ax = gpa[i][2] / fontSize * 1000f / FOP_FONTSIZE_FACTOR;
+ float ay = gpa[i][3] / FOP_FONTSIZE_FACTOR; // ignored in
horizontal typesetting
+
+ if (Math.abs(py) >= delta)
+ {
+ if (!ga.isEmpty())
+ {
+ contentStream.showGlyphsWithPositioning(ga);
+ ga.clear();
+ }
+ contentStream.setTextRise(py);
+ }
+ if (Math.abs(px) >= delta)
+ {
+ ga.add(-px);
+ }
+ ga.add(glyphIds[i]);
+
+ if (Math.abs(px) >= delta)
+ {
+ ga.add(px);
+ }
+ if (Math.abs(ax) >= delta)
+ {
+ ga.add(-ax);
+ }
+ if (Math.abs(py) >= delta)
+ {
+ contentStream.showGlyphsWithPositioning(ga);
+ ga.clear();
+ contentStream.setTextRise(0.0f);
+ }
+ if (Math.abs(ax) >= delta)
+ {
+ ga.add(ax);
+ }
+ }
+ if (!ga.isEmpty())
+ {
+ contentStream.showGlyphsWithPositioning(ga);
+ ga.clear();
+ }
+ }
+
+ /**
+ * Create a gpa with no corrections
+ *
+ * @param length of the text
+ * @return gpa filled with zeroes
+ */
+ protected int[][] createZeroGpa(int length)
+ {
+ int[][] gpa = new int[length][];
+ int[] z4 = new int[] { 0, 0, 0, 0 };
+ for (int i = 0; i < length; i++)
+ {
+ gpa[i] = z4;
+ }
+ return gpa;
+ }
+
+ /**
+ * Reverse gpa
+ *
+ * @param gpa positioning parameters
+ * @return reversed gpa
+ */
+ protected int[][] reverseGpa(int[][] gpa)
+ {
+ int[][] reversed = new int[gpa.length][];
+
+ for (int i = 0; i < gpa.length; i++)
+ {
+ int r = gpa.length - i - 1;
+ reversed[r] = gpa[i];
+ }
+ return reversed;
+ }
+}
Copied:
pdfbox/trunk/pdfbox-layout-fop/src/test/appended-resources/META-INF/LICENSE
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/appended-resources/META-INF/LICENSE)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ pdfbox/trunk/pdfbox-layout-fop/src/test/appended-resources/META-INF/LICENSE
Thu Jul 30 08:33:24 2026 (r1936716, copy of r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/appended-resources/META-INF/LICENSE)
@@ -0,0 +1,294 @@
+Lohit fonts (https://pagure.io/lohit):
+
+ Copyright 2011-15 Lohit Fonts Project contributors
+
+ This Font Software is licensed under the SIL Open Font License, Version
1.1.
+ This license is copied below, and is also available with a FAQ at:
+ http://scripts.sil.org/OFL
+
+
+ -----------------------------------------------------------
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+ -----------------------------------------------------------
+
+ PREAMBLE
+ The goals of the Open Font License (OFL) are to stimulate worldwide
+ development of collaborative font projects, to support the font creation
+ efforts of academic and linguistic communities, and to provide a free and
+ open framework in which fonts may be shared and improved in partnership
+ with others.
+
+ The OFL allows the licensed fonts to be used, studied, modified and
+ redistributed freely as long as they are not sold by themselves. The
+ fonts, including any derivative works, can be bundled, embedded,
+ redistributed and/or sold with any software provided that any reserved
+ names are not used by derivative works. The fonts and derivatives,
+ however, cannot be released under any other type of license. The
+ requirement for fonts to remain under this license does not apply
+ to any document created using the fonts or their derivatives.
+
+ DEFINITIONS
+ "Font Software" refers to the set of files released by the Copyright
+ Holder(s) under this license and clearly marked as such. This may
+ include source files, build scripts and documentation.
+
+ "Reserved Font Name" refers to any names specified as such after the
+ copyright statement(s).
+
+ "Original Version" refers to the collection of Font Software components as
+ distributed by the Copyright Holder(s).
+
+ "Modified Version" refers to any derivative made by adding to, deleting,
+ or substituting -- in part or in whole -- any of the components of the
+ Original Version, by changing formats or by porting the Font Software to a
+ new environment.
+
+ "Author" refers to any designer, engineer, programmer, technical
+ writer or other person who contributed to the Font Software.
+
+ PERMISSION & CONDITIONS
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
+ redistribute, and sell modified and unmodified copies of the Font
+ Software, subject to the following conditions:
+
+ 1) Neither the Font Software nor any of its individual components,
+ in Original or Modified Versions, may be sold by itself.
+
+ 2) Original or Modified Versions of the Font Software may be bundled,
+ redistributed and/or sold with any software, provided that each copy
+ contains the above copyright notice and this license. These can be
+ included either as stand-alone text files, human-readable headers or
+ in the appropriate machine-readable metadata fields within text or
+ binary files as long as those fields can be easily viewed by the user.
+
+ 3) No Modified Version of the Font Software may use the Reserved Font
+ Name(s) unless explicit written permission is granted by the corresponding
+ Copyright Holder. This restriction only applies to the primary font name as
+ presented to the users.
+
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+ Software shall not be used to promote, endorse or advertise any
+ Modified Version, except to acknowledge the contribution(s) of the
+ Copyright Holder(s) and the Author(s) or with their explicit written
+ permission.
+
+ 5) The Font Software, modified or unmodified, in part or in whole,
+ must be distributed entirely under this license, and must not be
+ distributed under any other license. The requirement for fonts to
+ remain under this license does not apply to any document created
+ using the Font Software.
+
+ TERMINATION
+ This license becomes null and void if any of the above conditions are
+ not met.
+
+ DISCLAIMER
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+ OTHER DEALINGS IN THE FONT SOFTWARE.
+
+
+FiraCode font:
+
+Copyright (c) 2014, The Fira Code Project Authors
(https://github.com/tonsky/FiraCode)
+SIL Open Font License, see above
+
+
+NotoSans Arabic font:
+
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/arabic)
+SIL Open Font License, see above
+
+
+Arimo font:
+
+Copyright 2026 The Arimo Project Authors
(https://github.com/googlefonts/arimo)
+SIL Open Font License, see above
+
+
+NotoSans Math font:
+
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/math)
+SIL Open Font License, see above
+
+
+NotoSans Thai font:
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/thai)
+
+
+Licenses for DejaVu font(s) (see also
https://www.apache.org/legal/resolved.html ):
+
+Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
+Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
+
+
+Bitstream Vera Fonts Copyright
+------------------------------
+
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
+a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the fonts accompanying this license ("Fonts") and associated
+documentation files (the "Font Software"), to reproduce and distribute the
+Font Software, including without limitation the rights to use, copy, merge,
+publish, distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright and trademark notices and this permission notice shall
+be included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular
+the designs of glyphs or characters in the Fonts may be modified and
+additional glyphs or characters may be added to the Fonts, only if the fonts
+are renamed to names not containing either the words "Bitstream" or the word
+"Vera".
+
+This License becomes null and void to the extent applicable to Fonts or Font
+Software that has been modified and is distributed under the "Bitstream
+Vera" names.
+
+The Font Software may be sold as part of a larger software package but no
+copy of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
+FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
+ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
+FONT SOFTWARE.
+
+Except as contained in this notice, the names of Gnome, the Gnome
+Foundation, and Bitstream Inc., shall not be used in advertising or
+otherwise to promote the sale, use or other dealings in this Font Software
+without prior written authorization from the Gnome Foundation or Bitstream
+Inc., respectively. For further information, contact: fonts at gnome dot org.
+
+Arev Fonts Copyright
+------------------------------
+
+Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the fonts accompanying this license ("Fonts") and
+associated documentation files (the "Font Software"), to reproduce
+and distribute the modifications to the Bitstream Vera Font Software,
+including without limitation the rights to use, copy, merge, publish,
+distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright and trademark notices and this permission notice
+shall be included in all copies of one or more of the Font Software
+typefaces.
+
+The Font Software may be modified, altered, or added to, and in
+particular the designs of glyphs or characters in the Fonts may be
+modified and additional glyphs or characters may be added to the
+Fonts, only if the fonts are renamed to names not containing either
+the words "Tavmjong Bah" or the word "Arev".
+
+This License becomes null and void to the extent applicable to Fonts
+or Font Software that has been modified and is distributed under the
+"Tavmjong Bah Arev" names.
+
+The Font Software may be sold as part of a larger software package but
+no copy of one or more of the Font Software typefaces may be sold by
+itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
+TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+
+Except as contained in this notice, the name of Tavmjong Bah shall not
+be used in advertising or otherwise to promote the sale, use or other
+dealings in this Font Software without prior written authorization
+from Tavmjong Bah. For further information, contact: tavmjong @ free . fr.
+
+TeX Gyre DJV Math
+-----------------
+Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
+
+Math extensions done by B. Jackowski, P. Strzelczyk and P. Pianowski
+(on behalf of TeX users groups) are in public domain.
+
+Letters imported from Euler Fraktur from AMSfonts are (c) American
Mathematical Society (see below).
+Bitstream Vera Fonts Copyright
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera
+is a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the fonts accompanying this license (“Fonts”) and associated documentation
+files (the “Font Software”), to reproduce and distribute the Font Software,
+including without limitation the rights to use, copy, merge, publish,
distribute,
+and/or sell copies of the Font Software, and to permit persons to whom
+the Font Software is furnished to do so, subject to the following conditions:
+
+The above copyright and trademark notices and this permission notice shall be
+included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular
+the designs of glyphs or characters in the Fonts may be modified and additional
+glyphs or characters may be added to the Fonts, only if the fonts are renamed
+to names not containing either the words “Bitstream” or the word “Vera”.
+
+This License becomes null and void to the extent applicable to Fonts or Font
Software
+that has been modified and is distributed under the “Bitstream Vera” names.
+
+The Font Software may be sold as part of a larger software package but no copy
+of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL,
+SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO
USE
+THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
+Except as contained in this notice, the names of GNOME, the GNOME Foundation,
+and Bitstream Inc., shall not be used in advertising or otherwise to promote
+the sale, use or other dealings in this Font Software without prior written
+authorization from the GNOME Foundation or Bitstream Inc., respectively.
+For further information, contact: fonts at gnome dot org.
+
+AMSFonts (v. 2.2) copyright
+
+The PostScript Type 1 implementation of the AMSFonts produced by and
+previously distributed by Blue Sky Research and Y&Y, Inc. are now freely
+available for general use. This has been accomplished through the cooperation
+of a consortium of scientific publishers with Blue Sky Research and Y&Y.
+Members of this consortium include:
+
+Elsevier Science IBM Corporation Society for Industrial and Applied
+Mathematics (SIAM) Springer-Verlag American Mathematical Society (AMS)
+
+In order to assure the authenticity of these fonts, copyright will be held by
+the American Mathematical Society. This is not meant to restrict in any way
+the legitimate use of the fonts, such as (but not limited to) electronic
+distribution of documents containing these fonts, inclusion of these fonts
+into other public domain or commercial font collections or computer
+applications, use of the outline data to create derivative fonts and/or
+faces, etc. However, the AMS does require that the AMS copyright notice be
+removed from any derivative versions of the fonts which have been altered in
+any way. In addition, to ensure the fidelity of TeX documents using Computer
+Modern fonts, Professor Donald Knuth, creator of the Computer Modern faces,
+has requested that any alterations which yield different font metrics be
+given a different name.
\ No newline at end of file
Copied and modified:
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutBidiTest.java
(from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutBidiTest.java)
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutBidiTest.java
Mon Jul 6 08:32:53 2026 (r1935929, copy source)
+++
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutBidiTest.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -14,11 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.pdfbox.glyphlayout.awt;
+package org.apache.pdfbox.glyphlayout.fop;
import org.junit.jupiter.api.Test;
-import java.awt.FontFormatException;
import java.io.IOException;
import java.net.URISyntaxException;
@@ -28,7 +27,7 @@ import org.apache.pdfbox.pdmodel.PDPageC
import org.apache.pdfbox.pdmodel.font.PDType0Font;
/**
- * Examples for bidirectional text with GlyphLayoutProcessorAwt
+ * Examples for bidirectional text with GlyphLayoutProcessorFop
*
* @author Volker Kunert
*/
@@ -74,9 +73,9 @@ public class GlyphLayoutBidiTest extends
}
@Test
- void testGlyphLayoutBidi() throws IOException, FontFormatException,
URISyntaxException
+ void testGlyphLayoutBidi() throws IOException, URISyntaxException
{
- GlyphLayoutProcessorAwt glyphLayoutProcessorAwt = new
GlyphLayoutProcessorAwt();
+ GlyphLayoutProcessorFop glyphLayoutProcessorFop = new
GlyphLayoutProcessorFop();
String outputName = "GlyphLayoutBidi.pdf";
String outputFilename = "target/" + outputName;
@@ -87,14 +86,14 @@ public class GlyphLayoutBidiTest extends
try (PDDocument doc = new PDDocument())
{
- PDType0Font arabicFont =
createPdType0Font(glyphLayoutProcessorAwt, doc, arabicPath);
- PDType0Font lgcFont = createPdType0Font(glyphLayoutProcessorAwt,
doc, lgcPath);
+ PDType0Font arabicFont =
createPdType0Font(glyphLayoutProcessorFop, doc, arabicPath);
+ PDType0Font lgcFont = createPdType0Font(glyphLayoutProcessorFop,
doc, lgcPath);
PDPage page = new PDPage();
doc.addPage(page);
try (PDPageContentStream cs = new PDPageContentStream(doc, page))
{
- cs.setGlyphLayoutProcessor(glyphLayoutProcessorAwt);
+ cs.setGlyphLayoutProcessor(glyphLayoutProcessorFop);
float x = page.getBBox().getLowerLeftX() + fontSize;
float y = page.getBBox().getUpperRightY() - fontSize;
Copied and modified:
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutDin91379FormTest.java
(from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutDin91379FormTest.java)
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutDin91379FormTest.java
Mon Jul 6 08:32:53 2026 (r1935929, copy source)
+++
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutDin91379FormTest.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -14,9 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.pdfbox.glyphlayout.awt;
+package org.apache.pdfbox.glyphlayout.fop;
-import java.awt.FontFormatException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -86,9 +85,9 @@ class GlyphLayoutDin91379FormTest extend
+ "Additional non-letters (not included in DIN 91379): – —
•�";
@Test
- void testGlyphLayoutDin91379Form() throws IOException,
FontFormatException, URISyntaxException
+ void testGlyphLayoutDin91379Form() throws IOException, URISyntaxException
{
- GlyphLayoutProcessorAwt glyphLayoutProcessor = new
GlyphLayoutProcessorAwt();
+ GlyphLayoutProcessorFop glyphLayoutProcessor = new
GlyphLayoutProcessorFop();
String outputName = "GlyphLayoutDIN91379Form.pdf";
String outputFilename = "target/" + outputName;
@@ -101,9 +100,7 @@ class GlyphLayoutDin91379FormTest extend
try (PDDocument doc = Loader.loadPDF(pdfForm))
{
// embedSubset has to be set to false
- // last parameter is just for test coverage
- PDType0Font font = glyphLayoutProcessor.loadFont(doc, fontStream,
- false, new GlyphLayoutFontLoaderAwt.FontOptions());
+ PDType0Font font = glyphLayoutProcessor.loadFont(doc, fontStream,
false);
PDDocumentCatalog docCatalog = doc.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
Copied and modified:
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutDin91379Test.java
(from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutDin91379Test.java)
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutDin91379Test.java
Mon Jul 6 08:32:53 2026 (r1935929, copy source)
+++
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutDin91379Test.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -14,9 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.pdfbox.glyphlayout.awt;
+package org.apache.pdfbox.glyphlayout.fop;
-import java.awt.FontFormatException;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
@@ -26,16 +25,17 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URISyntaxException;
-import org.apache.pdfbox.Loader;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
+import org.apache.pdfbox.Loader;
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.apache.pdfbox.text.PDFTextStripper;
-import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Example of formatting for letters defined in: DIN 91379: Characters in
Unicode for the electronic
@@ -91,9 +91,9 @@ class GlyphLayoutDin91379Test extends Te
+ "Additional non-letters (not included in DIN 91379): – —
•�";
@Test
- void testGlyphLayoutDin91379() throws IOException, FontFormatException,
URISyntaxException
+ void testGlyphLayoutDin91379() throws IOException, URISyntaxException
{
- GlyphLayoutProcessorAwt glyphLayoutProcessor = new
GlyphLayoutProcessorAwt();
+ GlyphLayoutProcessorFop glyphLayoutProcessor = new
GlyphLayoutProcessorFop();
String outputName = "GlyphLayoutDIN91379.pdf";
String outputPDFFilename = "target/" + outputName;
Copied and modified:
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutHelloWorldTest.java
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutHelloWorldAWTTest.java)
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutHelloWorldAWTTest.java
Sat Jul 25 14:39:51 2026 (r1936582, copy source)
+++
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutHelloWorldTest.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -14,31 +14,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.pdfbox.glyphlayout.awt;
+package org.apache.pdfbox.glyphlayout.fop;
-import java.awt.FontFormatException;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import org.junit.jupiter.api.Test;
-import org.apache.pdfbox.glyphlayout.examples.GlyphLayoutHelloWorldAWT;
+import org.apache.pdfbox.glyphlayout.examples.GlyphLayoutHelloWorldFOP;
/**
*
* @author Tilman Hausherr
*/
-class GlyphLayoutHelloWorldAWTTest extends TestBase
+class GlyphLayoutHelloWorldTest extends TestBase
{
@Test
- void testGlyphLayoutHelloWorldAWT() throws IOException,
FontFormatException, URISyntaxException
+ void testGlyphLayoutHelloWorld() throws IOException, URISyntaxException
{
String outputName = "HelloWorld.pdf";
- String lohitBengaliPath = "/ttf/Lohit-Bengali.ttf";
- File file = new
File(GlyphLayoutHelloWorldAWTTest.class.getResource(lohitBengaliPath).toURI());
- String [] args = new String[]{ "target/" + outputName, "হ্যালো
ওয়ার্ল্ড", file.getPath() };
- GlyphLayoutHelloWorldAWT.main(args);
+ String lohitBengaliPath = "/ttf/DejaVuSans.ttf";
+ File file = new
File(GlyphLayoutHelloWorldTest.class.getResource(lohitBengaliPath).toURI());
+ // Ligatures work by default for this font
+ String [] args = new String[]{ "target/" + outputName, "Effective",
file.getPath() };
+ GlyphLayoutHelloWorldFOP.main(args);
checkRenderIdent(outputName);
}
}
Copied and modified:
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutLigaturesAndKerningTest.java
(from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutLigaturesAndKerningTest.java)
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutLigaturesAndKerningTest.java
Mon Jul 6 08:32:53 2026 (r1935929, copy source)
+++
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutLigaturesAndKerningTest.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.pdfbox.glyphlayout.awt;
+package org.apache.pdfbox.glyphlayout.fop;
/**
* Examples for ligatures and kerning
@@ -27,7 +27,6 @@ package org.apache.pdfbox.glyphlayout.aw
* @author Volker Kunert
*/
-import java.awt.FontFormatException;
import java.io.IOException;
import java.net.URISyntaxException;
@@ -45,28 +44,24 @@ class GlyphLayoutLigaturesAndKerningTest
static final String FIRACODE_STRING = "!= == === >= <=";
static final String DEJAVU_STRING = "AVATAR, effective, affiliation,
float, film, affluent";
static final String BENGALI_STRING = "আমি কোন পথে ক্ষীরের লক্ষ্মী ষন্ড
পুতুল রুপো গঙ্গা ঋষি";
-
- // for code coverage at the end of showTextUni
- // happens only if font size 20 and the spaces
- static final String BENGALI_STRING2 = " আর সবই গেছে ঋণে।";
+ static final String THAI_STRING = "กูกินก้งปิ้งอยู่ในถ้ำ";
+ static final String BENGALI_STRING2 = "হ্যালো ওয়ার্ল্ড";
/**
* Check that missing glyph is caught like in main pdfbox.
*
* @throws IOException
- * @throws FontFormatException
*/
@Test
- void testMissingGlyph() throws IOException, FontFormatException
+ void testMissingGlyph() throws IOException
{
- GlyphLayoutProcessorAwt glyphLayoutProcessor = new
GlyphLayoutProcessorAwt();
+ GlyphLayoutProcessorFop glyphLayoutProcessor = new
GlyphLayoutProcessorFop();
String lohitBengaliPath = "/ttf/Lohit-Bengali.ttf";
try (PDDocument doc = new PDDocument())
{
- PDType0Font lohitBengaliFont =
createPdType0Font(glyphLayoutProcessor, doc, lohitBengaliPath,
- new GlyphLayoutFontLoaderAwt.FontOptions());
+ PDType0Font lohitBengaliFont =
createPdType0Font(glyphLayoutProcessor, doc, lohitBengaliPath);
PDPage page = new PDPage();
doc.addPage(page);
@@ -76,7 +71,7 @@ class GlyphLayoutLigaturesAndKerningTest
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());
+ 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
}
@@ -84,14 +79,15 @@ class GlyphLayoutLigaturesAndKerningTest
}
@Test
- void testLigaturesAndKerning() throws IOException, FontFormatException,
URISyntaxException
+ void testLigaturesAndKerning() throws IOException, URISyntaxException
{
- GlyphLayoutProcessorAwt glyphLayoutProcessor = new
GlyphLayoutProcessorAwt();
+ GlyphLayoutProcessorFop glyphLayoutProcessor = new
GlyphLayoutProcessorFop();
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 thaiPath = "/ttf/NotoSansThai-Regular.ttf";
String lohitBengaliPath = "/ttf/Lohit-Bengali.ttf";
float fontSize = 12.0f;
@@ -99,22 +95,19 @@ class GlyphLayoutLigaturesAndKerningTest
try (PDDocument doc = new PDDocument())
{
PDType0Font firaFont = createPdType0Font(glyphLayoutProcessor,
doc, firaPath);
- PDType0Font firaLigFont = createPdType0Font(glyphLayoutProcessor,
doc, firaPath,
- new
GlyphLayoutFontLoaderAwt.FontOptions().setLigaturesOn());
+ PDType0Font firaLigFont = createPdType0Font(glyphLayoutProcessor,
doc, firaPath);
PDType0Font dejavuFont = createPdType0Font(glyphLayoutProcessor,
doc, dejavuPath);
- PDType0Font dejavuLigFont =
createPdType0Font(glyphLayoutProcessor, doc, dejavuPath,
- new
GlyphLayoutFontLoaderAwt.FontOptions().setLigaturesOn());
+ PDType0Font dejavuLigFont =
createPdType0Font(glyphLayoutProcessor, doc, dejavuPath);
- PDType0Font dejavuKernFont =
createPdType0Font(glyphLayoutProcessor, doc, dejavuPath,
- new GlyphLayoutFontLoaderAwt.FontOptions().setKerningOn());
+ PDType0Font dejavuKernFont =
createPdType0Font(glyphLayoutProcessor, doc, dejavuPath);
- PDType0Font dejavuLigKernFont =
createPdType0Font(glyphLayoutProcessor, doc, dejavuPath,
- new
GlyphLayoutFontLoaderAwt.FontOptions().setLigaturesOn().setKerningOn());
-
- PDType0Font lohitBengaliFont =
createPdType0Font(glyphLayoutProcessor, doc, lohitBengaliPath,
- new GlyphLayoutFontLoaderAwt.FontOptions());
+ PDType0Font dejavuLigKernFont =
createPdType0Font(glyphLayoutProcessor, doc, dejavuPath);
+
+ PDType0Font thaiFont = createPdType0Font(glyphLayoutProcessor,
doc, thaiPath);
+
+ PDType0Font lohitBengaliFont =
createPdType0Font(glyphLayoutProcessor, doc, lohitBengaliPath);
PDPage page = new PDPage();
doc.addPage(page);
@@ -130,8 +123,18 @@ class GlyphLayoutLigaturesAndKerningTest
y = showComposites(cs, dejavuLigFont, fontSize, x, y,
DEJAVU_STRING + " (Ligatures)");
y = showComposites(cs, dejavuKernFont, fontSize, x, y,
DEJAVU_STRING + " (Kerning)");
y = showComposites(cs, dejavuLigKernFont, fontSize, x, y,
DEJAVU_STRING + " (Ligatures and kerning)");
- y = showComposites(cs, lohitBengaliFont, fontSize, x, y,
BENGALI_STRING + " (ভারত)");
- showComposites(cs, lohitBengaliFont, 20, x, y - 20,
BENGALI_STRING2 + " (ভারত)");
+ y = showComposites(cs, thaiFont, fontSize, x, y, THAI_STRING);
+ y = showComposites(cs, lohitBengaliFont, fontSize, x, y - 5,
BENGALI_STRING + " (ভারত)");
+
+ // from the related awt test. Unclear if useful in the future
if FOP ever supports bengali
+ // and we get access to it.
+ cs.beginText();
+ cs.setFont(lohitBengaliFont, 20);
+ cs.newLineAtOffset(x, y - 20);
+ cs.showText(BENGALI_STRING2);
+ cs.showText(" ");
+ cs.showText(BENGALI_STRING2);
+ cs.endText();
}
doc.save(outputFilename);
}
Copied and modified:
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutSMPTest.java
(from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutSMPTest.java)
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/GlyphLayoutSMPTest.java
Mon Jul 6 08:32:53 2026 (r1935929, copy source)
+++
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/GlyphLayoutSMPTest.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -15,9 +15,8 @@
* limitations under the License.
*/
-package org.apache.pdfbox.glyphlayout.awt;
+package org.apache.pdfbox.glyphlayout.fop;
-import java.awt.FontFormatException;
import java.io.IOException;
import java.net.URISyntaxException;
@@ -28,7 +27,7 @@ import org.apache.pdfbox.pdmodel.font.PD
import org.junit.jupiter.api.Test;
/**
- * Examples for Supplementary Multilingual Plane with GlyphLayoutProcessorAwt
that require a
+ * Examples for Supplementary Multilingual Plane with GlyphLayoutProcessorFop
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)
*
@@ -98,9 +97,9 @@ class GlyphLayoutSMPTest extends TestBas
}
@Test
- void testGlyphLayoutSMP() throws IOException, FontFormatException,
URISyntaxException
+ void testGlyphLayoutSMP() throws IOException, URISyntaxException
{
- GlyphLayoutProcessorAwt glyphLayoutProcessor = new
GlyphLayoutProcessorAwt();
+ GlyphLayoutProcessorFop glyphLayoutProcessor = new
GlyphLayoutProcessorFop();
String outputName = "GlyphLayoutSMP.pdf";
String outputFilename = "target/" + outputName;
Copied and modified:
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/TestBase.java
(from r1935929,
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/TestBase.java)
==============================================================================
---
pdfbox/trunk/pdfbox-layout-awt/src/test/java/org/apache/pdfbox/glyphlayout/awt/TestBase.java
Mon Jul 6 08:32:53 2026 (r1935929, copy source)
+++
pdfbox/trunk/pdfbox-layout-fop/src/test/java/org/apache/pdfbox/glyphlayout/fop/TestBase.java
Thu Jul 30 08:33:24 2026 (r1936716)
@@ -14,21 +14,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.pdfbox.glyphlayout.awt;
+package org.apache.pdfbox.glyphlayout.fop;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
-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;
/**
*
@@ -76,24 +77,16 @@ class TestBase
/**
* 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
+ PDType0Font createPdType0Font(GlyphLayoutProcessorFop
glyphLayoutProcessor, PDDocument doc,
+ String fontPath) throws IOException
{
try (InputStream fontStream =
this.getClass().getResourceAsStream(fontPath))
{
- return glyphLayoutProcessor.loadFont(doc, fontStream, fontOptions);
+ return glyphLayoutProcessor.loadFont(doc, fontStream);
}
}
+
/*
* show one line
*/
Copied: pdfbox/trunk/pdfbox-layout-fop/src/test/resources/log4j2.xml (from
r1936582, pdfbox/trunk/pdfbox-layout-awt/src/test/resources/log4j2.xml)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ pdfbox/trunk/pdfbox-layout-fop/src/test/resources/log4j2.xml Thu Jul
30 08:33:24 2026 (r1936716, copy of r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/log4j2.xml)
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ! 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.
+ !-->
+
+<!-- https://logging.apache.org/log4j/2.x/manual/configuration.html
+ https://logging.apache.org/log4j/2.x/manual/appenders.html
+-->
+<Configuration>
+ <Appenders>
+ <Console name="STDOUT" target="SYSTEM_OUT">
+ <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss} %-5p %C{2}:%L -
%m%n"/>
+ </Console>
+ <RollingFile name="FILE" fileName="target/pdfbox.log"
filePattern="target/pdfbox-%i.log">
+ <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss} %-5p %C{2}:%L -
%m%n"/>
+ <Policies>
+ <OnStartupTriggeringPolicy />
+ <SizeBasedTriggeringPolicy size="20 MB" />
+ </Policies>
+ <DefaultRolloverStrategy max="5"/>
+ </RollingFile>
+ </Appenders>
+ <Loggers>
+ <Root level="info">
+ <AppenderRef ref="STDOUT"/>
+ <AppenderRef ref="FILE"/>
+ </Root>
+ </Loggers>
+</Configuration>
Added: pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/GlyphLayoutBidi.pdf
==============================================================================
Binary file. No diff available.
Added:
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/GlyphLayoutDIN91379.pdf
==============================================================================
Binary file. No diff available.
Added:
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/GlyphLayoutDIN91379Form.pdf
==============================================================================
Binary file. No diff available.
Added:
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/GlyphLayoutLigaturesAndKerning.pdf
==============================================================================
Binary file. No diff available.
Added: pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/GlyphLayoutSMP.pdf
==============================================================================
Binary file. No diff available.
Copied and modified:
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/HelloWorld.pdf (from
r1936582, pdfbox/trunk/pdfbox-layout-awt/src/test/resources/pdf/HelloWorld.pdf)
==============================================================================
Binary file (source and/or target). No diff available.
Copied: pdfbox/trunk/pdfbox-layout-fop/src/test/resources/pdf/PdfForm.pdf (from
r1936582, pdfbox/trunk/pdfbox-layout-awt/src/test/resources/pdf/PdfForm.pdf)
==============================================================================
Binary file (source and/or target). No diff available.
Copied: pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/Arimo-Regular.ttf
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/Arimo-Regular.ttf)
==============================================================================
Binary file (source and/or target). No diff available.
Copied: pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/DejaVuSans.ttf
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/DejaVuSans.ttf)
==============================================================================
Binary file (source and/or target). No diff available.
Copied:
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/FiraCode-Regular.ttf
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/FiraCode-Regular.ttf)
==============================================================================
Binary file (source and/or target). No diff available.
Copied: pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/Lohit-Bengali.ttf
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/Lohit-Bengali.ttf)
==============================================================================
Binary file (source and/or target). No diff available.
Copied:
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/NotoSansArabic-Regular.ttf
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/NotoSansArabic-Regular.ttf)
==============================================================================
Binary file (source and/or target). No diff available.
Added:
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/NotoSansBengali-Regular.ttf
==============================================================================
Binary file. No diff available.
Copied:
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/NotoSansMath-Regular.ttf
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/NotoSansMath-Regular.ttf)
==============================================================================
Binary file (source and/or target). No diff available.
Copied:
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/ttf/NotoSansThai-Regular.ttf
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/ttf/NotoSansThai-Regular.ttf)
==============================================================================
Binary file (source and/or target). No diff available.
Copied:
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/txt/GlyphLayoutDIN91379.txt
(from r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/txt/GlyphLayoutDIN91379.txt)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++
pdfbox/trunk/pdfbox-layout-fop/src/test/resources/txt/GlyphLayoutDIN91379.txt
Thu Jul 30 08:33:24 2026 (r1936716, copy of r1936582,
pdfbox/trunk/pdfbox-layout-awt/src/test/resources/txt/GlyphLayoutDIN91379.txt)
@@ -0,0 +1,41 @@
+DIN 91379: Characters in Unicode for the electronic processing of names
+and data exchange in Europe
+Font used: Arimo-Regular.ttf
+bll; Latin Letters (normative)
+A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m
n o p q r s t u v w x y z
+À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç
è é ê ë ì í î ï ð ñ ò ó
+ô õ ö ø ù ú û ü ý þ ÿ Ā ā Ă ă Ą ą Ć ć Ĉ ĉ Ċ ċ Č č Ď ď Đ đ Ē ē Ĕ ĕ Ė ė Ę ę Ě ě
Ĝ ĝ Ğ ğ Ġ ġ Ģ ģ Ĥ ĥ Ħ
+ħ Ĩ ĩ Ī ī Ĭ ĭ Į į İ ı IJ ij Ĵ ĵ Ķ ķ ĸ Ĺ ĺ Ļ ļ Ľ ľ Ŀ ŀ Ł ł Ń ń Ņ ņ Ň ň ʼn Ŋ ŋ Ō ō
Ŏ ŏ Ő ő Œ œ Ŕ ŕ Ŗ ŗ Ř ř Ś ś Ŝ ŝ Ş
+ş Š š Ţ ţ Ť ť Ŧ ŧ Ũ ũ Ū ū Ŭ ŭ Ů ů Ű ű Ų ų Ŵ ŵ Ŷ ŷ Ÿ Ź ź Ż ż Ž ž Ƈ ƈ Ə Ɨ Ơ ơ Ư
ư Ʒ Ǎ ǎ Ǐ ǐ Ǒ ǒ Ǔ ǔ Ǖ ǖ
+Ǘ ǘ Ǚ ǚ Ǜ ǜ Ǟ ǟ Ǣ ǣ Ǥ ǥ Ǧ ǧ Ǩ ǩ Ǫ ǫ Ǭ ǭ Ǯ ǯ ǰ Ǵ ǵ Ǹ ǹ Ǻ ǻ Ǽ ǽ Ǿ ǿ Ȓ ȓ Ș ș Ț ț
Ȟ ȟ ȧ Ȩ ȩ Ȫ ȫ Ȭ ȭ
+Ȯ ȯ Ȱ ȱ Ȳ ȳ ə ɨ ʒ Ḃ ḃ Ḇ ḇ Ḋ ḋ Ḍ ḍ Ḏ ḏ Ḑ ḑ ḗ Ḝ ḝ Ḟ ḟ Ḡ ḡ Ḣ ḣ Ḥ ḥ Ḧ ḧ Ḩ ḩ Ḫ ḫ ḯ
Ḱ ḱ Ḳ ḳ Ḵ ḵ Ḷ ḷ Ḻ ḻ Ṁ
+ṁ Ṃ ṃ Ṅ ṅ Ṇ ṇ Ṉ ṉ Ṓ ṓ Ṕ ṕ Ṗ ṗ Ṙ ṙ Ṛ ṛ Ṟ ṟ Ṡ ṡ Ṣ ṣ Ṫ ṫ Ṭ ṭ Ṯ ṯ Ẁ ẁ Ẃ ẃ Ẅ ẅ Ẇ ẇ
Ẍ ẍ Ẏ ẏ Ẑ ẑ Ẓ ẓ Ẕ ẕ
+ẖ ẗ ẞ Ạ ạ Ả ả Ấ ấ Ầ ầ Ẩ ẩ Ẫ ẫ Ậ ậ Ắ ắ Ằ ằ Ẳ ẳ Ẵ ẵ Ặ ặ Ẹ ẹ Ẻ ẻ Ẽ ẽ Ế ế Ề ề Ể ể
Ễ ễ Ệ ệ Ỉ ỉ Ị ị Ọ ọ Ỏ ỏ Ố
+ố Ồ ồ Ổ ổ Ỗ ỗ Ộ ộ Ớ ớ Ờ ờ Ở ở Ỡ ỡ Ợ ợ Ụ ụ Ủ ủ Ứ ứ Ừ ừ Ử ử Ữ ữ Ự ự Ỳ ỳ Ỵ ỵ Ỷ ỷ
Ỹ ỹ
+Sequences
+A̋ C̀ C̄ C̆ C̈ C̕ C̣ C̦ C̨̆ D̂ F̀ F̄ G̀ H̄ H̦ H̱ J́ J̌ K̀ K̂ K̄ K̇ K̕ K̛ K̦
K͟H
+K͟h L̂ L̥ L̥̄ L̦ M̀ M̂ M̆ M̐ N̂ N̄ N̆ N̦ P̀ P̄ P̕ P̣ R̆ R̥ R̥̄ S̀ S̄ S̛̄ S̱ T̀
T̄
+T̈ T ̕T̛ U̇ Z̀ Z̄ Z̆ Z̈ Z̧ a̋ c̀ c̄ c̆ c̈ c̕ c ̣c̦ c̨̆ d̂ f ̀f̄ g̀ h̄ h̦ ȷ ́k̀
+k̂ k̄ k̇ k ̕k̛ k̦ k͟h l̂ l̥ l̥̄ l̦ m̀ m̂ m̆ m̐ n̂ n̄ n̆ n̦ p̀ p̄ p̕ p ̣r̆ r̥
r̥̄
+s̀ s̄ s̛̄ s̱ t̀ t̄ t̕ t̛ u̇ z̀ z̄ z̆ z̈ z̧ Ç̆ Û̄ ç̆ û̄ ÿ́ Č̕ Č̣ č ̕č ̣ē̍ Ī́ ī́
+ō̍ Ž̦ Ž̧ ž̦ ž̧ Ḳ̄ ḳ̄ Ṣ̄ ṣ̄ Ṭ̄ ṭ̄ Ạ̈ ạ̈ Ọ̈ ọ̈ Ụ̄ Ụ̈ ụ̄ ụ̈
+bnlreq; Non-Letters N1 (normative)
+ ' , - . ` ~ ¨ ´ · ʹ ʺ ʾ ʿ ˈ ˌ ’ ‡
+bnl; Non-Letters N2 (normative)
+! " # $ % & ( ) * + / 0 1 2 3 4 5 6 7 8 9 : ; < = >
+? @ [ \ ] ^ _ { | } ¡ ¢ £ ¥ § © ª « ¬ ® ¯ ° ± ² ³ µ
+¶ ¹ º » ¿ × ÷ €
+bnlopt; Non-Letters N3 (normative)
+¤ ¦ ¸ ¼ ½ ¾
+gl; Greek Letters (extended)
+Ά Έ Ή Ί Ό Ύ Ώ ΐ Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ
+Τ Υ Φ Χ Ψ Ω Ϊ Ϋ ά έ ή ί ΰ α β γ δ ε ζ η θ ι κ λ μ ν
+ξ ο π ρ ς σ τ υ φ χ ψ ω ϊ ϋ ό ύ ώ
+cl; Cyrillic Letters (extended)
+Ѝ А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш
+Щ Ъ Ь Ю Я а б в г д е ж з и й к л м н о п р с т у ф
+х ц ч ш щ ъ ь ю я ѝ
+enl; Non-Letters E1 (extended)
+ƒ ʰ ʳ ˆ ˜ ˢ ᵈ ᵗ ‘ ‚ “ ” „ † … ‰ ′ ″ ‹ › ⁰ ⁴ ⁵ ⁶ ⁷ ⁸
+⁹ ⁿ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ™ ∞ ≤ ≥
+Additional non-letters (not included in DIN 91379): – — •�
Modified: pdfbox/trunk/pom.xml
==============================================================================
--- pdfbox/trunk/pom.xml Thu Jul 30 08:30:47 2026 (r1936715)
+++ pdfbox/trunk/pom.xml Thu Jul 30 08:33:24 2026 (r1936716)
@@ -37,6 +37,7 @@
<module>xmpbox</module>
<module>pdfbox</module>
<module>pdfbox-layout-awt</module>
+ <module>pdfbox-layout-fop</module>
<module>debugger</module>
<module>tools</module>
<module>app</module>