This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new b0790c7bf7 Fixes #9323. Embed FontBox CMaps in the pdf native image
b0790c7bf7 is described below
commit b0790c7bf71f99abaf425e33faf9c811609105a7
Author: Jiří Ondrušek <[email protected]>
AuthorDate: Thu Oct 15 08:17:46 2026 +0200
Fixes #9323. Embed FontBox CMaps in the pdf native image
FontBox loads predefined CMaps such as Identity-H from
org/apache/fontbox/cmap by names computed at runtime, so GraalVM did not
embed them. Text extraction from PDFs with Type0 fonts using e.g. the
Identity-H encoding failed in native mode with "Could not find referenced
cmap stream Identity-H".
Register the whole directory, as any predefined CMap can be referenced.
A new test extracts text from a PDF with an Identity-H font.
Co-authored-by: jiriOndrusek-agent <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
---
.../component/pdf/deployment/PdfProcessor.java | 6 ++++
.../quarkus/component/pdf/it/PdfResource.java | 8 ++++++
.../camel/quarkus/component/pdf/it/PdfTest.java | 32 ++++++++++++++++++++++
3 files changed, 46 insertions(+)
diff --git
a/extensions/pdf/deployment/src/main/java/org/apache/camel/quarkus/component/pdf/deployment/PdfProcessor.java
b/extensions/pdf/deployment/src/main/java/org/apache/camel/quarkus/component/pdf/deployment/PdfProcessor.java
index ae29bd9bbe..498cdad7a8 100644
---
a/extensions/pdf/deployment/src/main/java/org/apache/camel/quarkus/component/pdf/deployment/PdfProcessor.java
+++
b/extensions/pdf/deployment/src/main/java/org/apache/camel/quarkus/component/pdf/deployment/PdfProcessor.java
@@ -48,6 +48,12 @@ class PdfProcessor {
return new
NativeImageResourceDirectoryBuildItem("org/apache/pdfbox/resources");
}
+ @BuildStep
+ NativeImageResourceDirectoryBuildItem registerFontBoxCMaps() {
+ // FontBox loads predefined CMaps (e.g. Identity-H) by names computed
at runtime
+ return new
NativeImageResourceDirectoryBuildItem("org/apache/fontbox/cmap");
+ }
+
@BuildStep
void
configureRuntimeInitializedClasses(BuildProducer<RuntimeInitializedClassBuildItem>
runtimeInitializedClass) {
for (String className : RUNTIME_INITIALIZED_CLASSES) {
diff --git
a/integration-tests/pdf/src/main/java/org/apache/camel/quarkus/component/pdf/it/PdfResource.java
b/integration-tests/pdf/src/main/java/org/apache/camel/quarkus/component/pdf/it/PdfResource.java
index 77976fba25..20d08d3939 100644
---
a/integration-tests/pdf/src/main/java/org/apache/camel/quarkus/component/pdf/it/PdfResource.java
+++
b/integration-tests/pdf/src/main/java/org/apache/camel/quarkus/component/pdf/it/PdfResource.java
@@ -88,6 +88,14 @@ public class PdfResource {
return producerTemplate.requestBody("pdf:extractText",
Loader.loadPDF(document), String.class);
}
+ @Path("/extractText")
+ @POST
+ @Consumes(MediaType.APPLICATION_OCTET_STREAM)
+ @Produces(MediaType.TEXT_PLAIN)
+ public String extractText(byte[] rawDocument) {
+ return producerTemplate.requestBody("pdf:extractText", rawDocument,
String.class);
+ }
+
@Path("/encrypt/standard")
@POST
@Produces(MediaType.TEXT_PLAIN)
diff --git
a/integration-tests/pdf/src/test/java/org/apache/camel/quarkus/component/pdf/it/PdfTest.java
b/integration-tests/pdf/src/test/java/org/apache/camel/quarkus/component/pdf/it/PdfTest.java
index a7ee390fed..b45217b558 100644
---
a/integration-tests/pdf/src/test/java/org/apache/camel/quarkus/component/pdf/it/PdfTest.java
+++
b/integration-tests/pdf/src/test/java/org/apache/camel/quarkus/component/pdf/it/PdfTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.quarkus.component.pdf.it;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
@@ -28,7 +29,10 @@ import io.smallrye.common.os.OS;
import org.apache.commons.io.FileUtils;
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.encryption.InvalidPasswordException;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.text.PDFTextStripper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
@@ -89,6 +93,34 @@ class PdfTest {
assertTrue(pdfText.contains("another line that should be appended"));
}
+ @Test
+ public void extractTextWithIdentityHFont() throws IOException {
+ // PDType0Font embeds the font with the Identity-H encoding, a
predefined CMap which FontBox loads by name
+ ByteArrayOutputStream pdf = new ByteArrayOutputStream();
+ try (PDDocument doc = new PDDocument();
+ InputStream font = PdfTest.class
+
.getResourceAsStream("/org/apache/pdfbox/resources/ttf/LiberationSans-Regular.ttf"))
{
+ PDPage page = new PDPage();
+ doc.addPage(page);
+ try (PDPageContentStream content = new PDPageContentStream(doc,
page)) {
+ content.beginText();
+ content.setFont(PDType0Font.load(doc, font), 12);
+ content.newLineAtOffset(50, 700);
+ content.showText("Identity-H encoded text");
+ content.endText();
+ }
+ doc.save(pdf);
+ }
+
+ RestAssured.given()
+ .contentType(ContentType.BINARY)
+ .body(pdf.toByteArray())
+ .post("/pdf/extractText")
+ .then()
+ .statusCode(200)
+ .body(containsString("Identity-H encoded text"));
+ }
+
@Test
public void merge() throws IOException {
byte[] bytesFirstPDF =
RestAssured.given().contentType(ContentType.TEXT)