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)

Reply via email to