flyingsaucerproject / flyingsaucer

XML/XHTML and CSS 2.1 renderer in pure Java
Other
2.02k stars 564 forks source link

Issue with Barcode128 FSImage after upgrade to 9.11.0 #444

Closed jenthomas88 closed 14 hours ago

jenthomas88 commented 3 days ago

Hello !

Since upgrade from 9.10.2 to 9.11.0, the barcodes are displayed too too small in the PDF generated. 9.10.2: image 9.11.0: image

This is my HTML:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div>
    <img th:src="PR12345678" type="code128" style="height: 100px"/>
    <div th:text="PR12345678"></div>
</div>
</body>
</html>

This is my generation code:

    public void run(Path processedFile, Path completedFile, List<GeneratorFeature> features) {
        try (FileOutputStream baos = new FileOutputStream(completedFile.toFile())) {
            ITextRenderer renderer = ITextRenderer.fromUrl(processedFile.toUri().toString());
            if (features != null && features.contains(GeneratorFeature.FS_REF_BARCODE)) {
                renderer.getSharedContext().setReplacedElementFactory(new BarcodeReplacedElementFactory(renderer.getOutputDevice()));
            }
            renderer.layout();
            renderer.createPDF(baos);
        } catch (Exception e) {
        }
    }

This is BarcodeReplacedElementFactory class:

@Slf4j
public class BarcodeReplacedElementFactory extends ITextReplacedElementFactory {

    public BarcodeReplacedElementFactory(ITextOutputDevice outputDevice) {
        super(outputDevice);
    }

    @Override
    public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, UserAgentCallback uac, int cssWidth, int cssHeight) {

        Element e = box.getElement();
        if (e == null) {
            return null;
        }

        String nodeName = e.getNodeName();
        if (nodeName.equals("img") && "code128".equals(e.getAttribute("type"))) {
            try {
                Barcode128 code = new Barcode128();
                code.setCode(e.getAttribute("src"));
                FSImage fsImage = new ITextFSImage(
                        Image.getInstance(code.createAwtImage(Color.BLACK, Color.WHITE), Color.WHITE));
                if (cssWidth != -1 || cssHeight != -1) {
                    fsImage.scale(cssWidth, cssHeight);
                }
                return new ITextImageElement(fsImage);
            } catch (Throwable e1) {
                log.error("Error in creating ITextFSImage: ", e1);
                return null;
            }
        }

        return super.createReplacedElement(c, box, uac, cssWidth, cssHeight);
    }
}

Is this a bug in the new version or do I have to change my barcode replacement method ?

Thank you for reading me !

asolntsev commented 2 days ago

@jenthomas88 Please pay attention to IDEA warnings. I believe IDE highlights this line as a warning:

    fsImage.scale(cssWidth, cssHeight);

This is because class FSImage is now immutable, and method fsImage.scale(...) returns a NEW instance. You need to slightly modify your code to use this new instance returned by scale method.

P.S. Do you use some external dependency for generating bar codes? Seems like a nice feature to add to FS.

jenthomas88 commented 1 day ago

Thanks, it's working now. Yes you are right, there was an IDEA highlight and I just didn't notice.

There's no need for an external lib, com.lowagie.text.pdf.Barcode128 is included in com.github.librepdf:openpdf that is already a dependency of FS.