OpenPDF icon indicating copy to clipboard operation
OpenPDF copied to clipboard

Openpdf does not apply font

Open josemrfl opened this issue 1 year ago • 2 comments

We are trying to migrate our application from the Itextpdf to Openpdf and we are finding problems with openpdf registering the font and styles we were already using.

It does not apply them correctly and seems to be picking up a default font and size making it sloppy.

/** The Constant PDF_INF_FONTS. */ private static final String PDF_INF_FONTS = "/reports/fonts/trebuc.ttf";

/** The Constant MAIN_FONT. */ private static final String MAIN_FONT = "trebuchet ms";

static { try { FontFactory.register(PDF_INF_FONTS, MAIN_FONT); } catch (final Exception e) { LOG.error("Specific font could not be registered for pdf generation", e); } }

private static void registerFonts(final ParametersExport parametrosExportacion) { letraCabeceras = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 9, Font.NORMAL, new Color(53, 46, 109)); letraFechasPar = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 7, Font.NORMAL, new Color(53, 46, 109)); letraFechasImpar = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 7, Font.NORMAL, new Color(255, 255, 255)); black = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 7, Font.NORMAL, Color.BLACK); blackBold = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 7, Font.BOLD, Color.BLACK); etiquetaIndicadores = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 6, Font.NORMAL, new Color(80, 88, 91)); letraIndicadores = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 1, Font.NORMAL, Color.BLACK); red = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 7, Font.NORMAL, new Color(178, 34, 34)); blue = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 7, Font.NORMAL, new Color(0, 0, 205)); }

On the left side an example of what the code generates using ItextPDF and on the right what OpenPDF generates, not applying the font, nor the size or style

Screenshots

image

  • OS: Windows 11 Pro
  • Used font: trebuchet ms
  • OpenPDF version: 1.3.36

josemrfl avatar Sep 09 '24 13:09 josemrfl

I created a test case based on the code you provided. According to ChatGPT the image has the font Trebuchet Ms.

Can you please create a full Junit test which demonstrates how you create the full PDF file, how you initialize the fonts and create the text.

Here are the results:

Image with font: image

This PDF file was generated: test_semana_output.pdf

Java test case:

package com.lowagie.text.pdf.fonts;

import static org.junit.jupiter.api.Assertions.*;

import com.lowagie.text.*;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import org.junit.jupiter.api.Test;

import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class FontRegistrationTest {

    private static final String PDF_INF_FONTS = "trebuc.ttf";
    private static final String MAIN_FONT = "trebuchet ms";
    private static final String OUTPUT_PDF_PATH = "test_semana_output.pdf";

    @Test
    public void testCreatePdfWithRegisteredFontAndTable() {
        // Register the font
        try {
            FontFactory.register(PDF_INF_FONTS, MAIN_FONT);
        } catch (Exception e) {
            fail("Font registration failed: " + e.getMessage());
        }

        // Create a PDF document using the registered fonts
        Document document = new Document();
        try (FileOutputStream fos = new FileOutputStream(OUTPUT_PDF_PATH)) {
            PdfWriter.getInstance(document, fos);
            document.open();

            // Create fonts for the PDF
            Font headerFont = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 12, Font.BOLD, Color.BLACK);
            Font bodyFont = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 10, Font.NORMAL, new Color(53, 46, 109));
            Font tableFont = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 9, Font.NORMAL, Color.BLACK);
            Font smallFont = FontFactory.getFont(MAIN_FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 8, Font.NORMAL, Color.GRAY);

            // Add "Semana" header
            Paragraph semanaHeader = new Paragraph("SEMANA 18 | 29/04/2024 - 05/05/2024", headerFont);
            semanaHeader.setAlignment(Element.ALIGN_CENTER);
            document.add(semanaHeader);
            document.add(Chunk.NEWLINE);

            // Add a simple drawing or placeholder for the image (a rectangle here)
            document.add(new Paragraph("Image Placeholder", smallFont));
            document.add(new Paragraph(" ", smallFont)); // Space for the image

            // Add mock data section with similar layout
            Paragraph mockDataHeader = new Paragraph("0/0/0", headerFont);
            mockDataHeader.setAlignment(Element.ALIGN_CENTER);
            document.add(mockDataHeader);

            Paragraph mockDataContent = new Paragraph("MOCK DATA MOCK DATA MOCK DATA", bodyFont);
            mockDataContent.setAlignment(Element.ALIGN_CENTER);
            document.add(mockDataContent);
            document.add(Chunk.NEWLINE);

            // Create a table like the one in the image
            PdfPTable table = new PdfPTable(4); // 4 columns
            table.setWidthPercentage(100);
            table.setSpacingBefore(10f);
            table.setSpacingAfter(10f);

            // Add the mock data cells
            for (int i = 0; i < 4; i++) {
                table.addCell(new Phrase("Mock Data", tableFont));
            }

            document.add(table);

            document.close();

            // Verify the PDF file has been created successfully
            File outputFile = new File(OUTPUT_PDF_PATH);
            assertTrue(outputFile.exists(), "PDF file should be created.");
            assertTrue(outputFile.length() > 0, "PDF file should not be empty.");

        } catch (DocumentException | IOException e) {
            fail("Failed to create PDF: " + e.getMessage());
        } finally {
            if (document.isOpen()) {
                document.close();
            }
        }
    }
}

andreasrosdal avatar Sep 11 '24 06:09 andreasrosdal

Hi @andreasrosdal, On the first time, thanks so much for your help.

I can't upload the application's code for legal reasons, but honestly, it's quite strange. I tried generating a PDF using your unit test with the OpenPDF library, and it correctly applies both the font, sizes, and styles.

However, I later tried implementing another test that calls the method in my service to export PDFs, where I do exactly the same to register and use the font, and here it's not applying it. Moreover, I even tried putting the code from your test inside my service, and it still doesn’t apply it correctly.

I made sure to have the trebuc.ttf font in the classpath of my project and verified that it’s loading correctly with URL fontUrl = getClass().getClassLoader().getResource("trebuc.ttf");

No exception occurs when registering the font either, but in the generated PDF, if I check the document properties and look at the fonts used, TrebuchetMS doesn’t appear.

What could be happening here? With ItexPdf, I don't have this kind of issue. I am attaching the PDF generated by my export service, where it doesn’t have the TrebuchetMS font

CP Openpdf test.pdf image

josemrfl avatar Oct 04 '24 10:10 josemrfl

Any clue about what could be going on here?

jsmanrique avatar Nov 05 '24 17:11 jsmanrique

I got a same problem. i try to miragte from itext 5 to openpdf 2.0.3 using fonts THSarabunNew but when i generate PDF from template PDF that use pdf version 1.7 after check result i found it's use default font (Helvetica not support thai language) so thai language in pdf disappear and eng lang font size not apply but when i use template PDF that use pdf version 1.6 it's work correctly. my code look like this :


            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            PdfReader reader = new PdfReader(pdfByteArray);
            PdfStamper stamper = new PdfStamper(reader, outputStream);
            AcroFields form = stamper.getAcroFields();
            form.setGenerateAppearances(true);

            for (AcroField acroField : list) {
                BaseFont baseFont = BaseFont.createFont("/fonts/THSarabunNew.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
                form.setFieldProperty(acroField.getKey(), "textsize", 12f, null);
                form.setFieldProperty(acroField.getKey(), "textfont", baseFont, null);
                form.setField(acroField.getKey(), acroField.getValue());
            }
            stamper.setFormFlattening(true);
            stamper.close();
            reader.close();

juloung123 avatar Apr 10 '25 04:04 juloung123

I got a same problem. i try to miragte from itext 5 to openpdf 2.0.3 using fonts THSarabunNew but when i generate PDF from template PDF that use pdf version 1.7 after check result i found it's use default font (Helvetica not support thai language) so thai language in pdf disappear and eng lang font size not apply but when i use template PDF that use pdf version 1.6 it's work correctly. my code look like this :


            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            PdfReader reader = new PdfReader(pdfByteArray);
            PdfStamper stamper = new PdfStamper(reader, outputStream);
            AcroFields form = stamper.getAcroFields();
            form.setGenerateAppearances(true);

            for (AcroField acroField : list) {
                BaseFont baseFont = BaseFont.createFont("/fonts/THSarabunNew.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
                form.setFieldProperty(acroField.getKey(), "textsize", 12f, null);
                form.setFieldProperty(acroField.getKey(), "textfont", baseFont, null);
                form.setField(acroField.getKey(), acroField.getValue());
            }
            stamper.setFormFlattening(true);
            stamper.close();
            reader.close();

Same problem here.

LE: I fiexd the issue with: form.regenerateField(fieldName);

But I still think it should have worked without.

cricrian avatar May 20 '25 16:05 cricrian