Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't fallback Font to Helvetica in PdfGraphics2D #1159

Open
admannon opened this issue May 2, 2024 · 6 comments
Open

Can't fallback Font to Helvetica in PdfGraphics2D #1159

admannon opened this issue May 2, 2024 · 6 comments
Labels

Comments

@admannon
Copy link

admannon commented May 2, 2024

PLEASE FILL THIS TEMPLATE AS MUCH AS POSSIBLE. REMOVE IRRELEVANT PARTS.

Describe the bug

We can't generate PDF document from code below and got error:

Font creation failed for Helvetica.
java.lang.RuntimeException: Font creation failed for Helvetica.

To Reproduce

Code to reproduce the issue

Unit Test

import com.lowagie.text.Document;
import com.lowagie.text.pdf.LayoutProcessor;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;
import org.junit.jupiter.api.Test;

import java.awt.*;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.print.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

class PdfConverterTest {

    private static int generateContent(Graphics g, PageFormat pf, int i) {
        var   g2 = (Graphics2D) g;
        float h  = (float) pf.getHeight();
        float w  = (float) pf.getWidth();

        Ellipse2D.Double circle = new Ellipse2D.Double();
        Ellipse2D.Double oval   = new Ellipse2D.Double();
        Ellipse2D.Double leaf   = new Ellipse2D.Double();
        Ellipse2D.Double stem   = new Ellipse2D.Double();
        g2.setColor(Color.green);

        double eh = h / 2;
        double ew = w / 2;
        leaf.setFrame(ew - 16, eh - 29, 15.0, 15.0);
        Area leaf1 = new Area(leaf);
        leaf.setFrame(ew - 14, eh - 47, 30.0, 30.0);
        Area leaf2 = new Area(leaf);
        leaf1.intersect(leaf2);
        g2.fill(leaf1);

        // Creates the second leaf.
        leaf.setFrame(ew + 1, eh - 29, 15.0, 15.0);
        leaf1 = new Area(leaf);
        leaf2.intersect(leaf1);
        g2.fill(leaf2);

        g2.setColor(Color.black);

        // Creates the stem by filling the Area resulting from the subtraction of two Area objects created from an
        // ellipse.
        stem.setFrame(ew, eh - 42, 40.0, 40.0);
        Area st1 = new Area(stem);
        stem.setFrame(ew + 3, eh - 47, 50.0, 50.0);
        Area st2 = new Area(stem);
        st1.subtract(st2);
        g2.fill(st1);

        g2.setColor(Color.yellow);

        // Creates the pear itself by filling the Area resulting from the union of two Area objects created by two
        // different ellipses.
        circle.setFrame(ew - 25, eh, 50.0, 50.0);
        oval.setFrame(ew - 19, eh - 20, 40.0, 70.0);

        Area circ = new Area();
        circ.add(new Area(circle));
        circ.add(new Area(oval));
        g2.fill(circ);
        g2.setColor(Color.black);
        g2.setFont(new Font("Arial", Font.PLAIN, 18));
        String      pear    = "Pear";
        FontMetrics metrics = g2.getFontMetrics();
        int         width   = metrics.stringWidth(pear);
        g2.drawString(pear, (w - width) / 2, 20);

        return Printable.PAGE_EXISTS;
    }

    private static PageFormat getPageFormat(double width, double height, int orientation) {
        PageFormat pageFormat = new PageFormat();
        Paper      paper      = pageFormat.getPaper();
        paper.setSize(width, height);
        paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
        pageFormat.setPaper(paper);
        pageFormat.setOrientation(orientation);
        return pageFormat;
    }

    @Test
    void generateFromPageable() throws IOException, PrinterException {
        Book book = new Book();
        book.append(
                PdfConverterTest::generateContent,
                getPageFormat(595.2755905511812, 841.8897637795277, PageFormat.PORTRAIT));

        LayoutProcessor.enable();

        byte[] pdfContentByte;
        try (var outputStream = new ByteArrayOutputStream()) {
            try (var document = new Document()) {
                var writer = PdfWriter.getInstance(document, outputStream);
                document.open();

                var contentByte = writer.getDirectContent();
                var totalPages  = book.getNumberOfPages();
                for (var i = 0; i < totalPages; i++) {
                    var   pageFormat = book.getPageFormat(i);
                    var   printable  = book.getPrintable(i);
                    float pageW      = (float) pageFormat.getWidth();
                    float pageH      = (float) pageFormat.getHeight();
                    float marginL    = (float) pageFormat.getImageableX();
                    float marginT    = (float) pageFormat.getImageableY();
                    float marginR    = (float) (pageW - pageFormat.getImageableWidth());
                    float marginB    = (float) (pageH - pageFormat.getImageableHeight());

                    document.setPageSize(new com.lowagie.text.Rectangle(pageW, pageH));
                    document.setMargins(marginL, marginR, marginT, marginB);
                    document.newPage();

                    Graphics2D g2 = contentByte.createGraphics(pageW, pageH);
                    printable.print(g2, pageFormat, i);
                    g2.dispose();
                    contentByte.sanityCheck();
                }
            }
            pdfContentByte = outputStream.toByteArray();
        }

        try (var inputStream = new ByteArrayInputStream(pdfContentByte)) {
            new PdfReader(inputStream);
        }
    }
}

Expected behavior

This code should generate a PDF normally

System

(please complete the following information)

  • OS: MacOS 14.4.1
  • Used font: new Font(Font.SANS_SERIF, Font.PLAIN, 12)
  • OpenPDF version: 2.0.2
@admannon admannon added the bug label May 2, 2024
@a-leithner
Copy link

I'm observing the same problem. However, in my case, I can generate one PDF without problems, but subsequent PDFs fail with this exact exception, though I'm also getting

Caused by: java.io.IOException: Helvetica not found as file or resource.
	at com.lowagie.text.pdf.LayoutProcessor.loadFont(LayoutProcessor.java:307)

If that's related, I'm using the technique discussed by V-F in #1078 to render an SVG image.

@a-leithner
Copy link

Oh, and version 2.0.1 of OpenPDF works fine, only 2.0.2 breaks.

@asturio
Copy link
Member

asturio commented May 27, 2024

Ok, that is strange. Maybe there is a problem or difference resolving the font-resource. There were some changes so the tests also work on Windows.

Keeping the tests compatible in Windows, Unix and Mac is not easy, as I only have access to the first 2.

@admannon can you verify, that the error don't occur with 2.0.1?

@asturio
Copy link
Member

asturio commented May 27, 2024

It's also a strange behaviour, as helvetica may be a font provided by the OS, but there are helvetica-font-files also in the JAR.

@a-leithner
Copy link

Well, I'm on Linux and don't have any form of Helvetica installed. Could this influence something?

@admannon
Copy link
Author

Ok, that is strange. Maybe there is a problem or difference resolving the font-resource. There were some changes so the tests also work on Windows.

Keeping the tests compatible in Windows, Unix and Mac is not easy, as I only have access to the first 2.

@admannon can you verify, that the error don't occur with 2.0.1?

Apologies for the delayed response. Yes, this error don't occur with OpenPDF v2.0.1. The attached PDF was generated using OpenPDF v2.0.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants