All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netgrif.application.engine.pdf.generator.service.PdfDrawer Maven / Gradle / Ivy

Go to download

System provides workflow management functions including user, role and data management.

There is a newer version: 6.3.3
Show newest version
package com.netgrif.application.engine.pdf.generator.service;

import com.netgrif.application.engine.pdf.generator.config.PdfResource;
import com.netgrif.application.engine.pdf.generator.config.types.PdfBooleanFormat;
import com.netgrif.application.engine.pdf.generator.domain.PdfField;
import com.netgrif.application.engine.pdf.generator.service.interfaces.IPdfDrawer;
import com.netgrif.application.engine.pdf.generator.service.renderer.*;
import com.netgrif.application.engine.petrinet.domain.dataset.FieldType;
import lombok.Setter;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.multipdf.PDFCloneUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.util.Matrix;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static com.netgrif.application.engine.pdf.generator.service.renderer.Renderer.removeUnsupportedChars;

/**
 * A drawer service that is able to draw elements to a content stream
 */
@Service
public class PdfDrawer implements IPdfDrawer {

    private PDDocument pdf;

    @Setter
    private PDDocument templatePdf;

    private PDPageContentStream contentStream;

    private List pageList;

    private PDPage currentPage = null;

    private PdfResource resource;

    private int marginBottom;
    private int lineHeight, padding;
    private int boxSize;

    public void setupDrawer(PDDocument pdf, PdfResource pdfResource) {
        this.pdf = pdf;
        this.resource = pdfResource;
        this.pageList = new ArrayList<>();
        this.marginBottom = resource.getMarginBottom();
        this.lineHeight = resource.getLineHeight();
        this.padding = resource.getPadding();
        this.boxSize = resource.getBoxSize();
    }

    @Override
    public void closeContentStream() throws IOException {
        contentStream.close();
        contentStream = null;
    }

    @Override
    public void closeTemplate() throws IOException {
        if (templatePdf != null) {
            templatePdf.close();
            templatePdf = null;
        }
    }

    @Override
    public void newPage() throws IOException {
        if (contentStream != null) {
            contentStream.close();
        }
        PDPage emptyPage;
        PDFCloneUtility cloneUtility = new PDFCloneUtility(templatePdf);
        if (!isOnLastPage()) {
            currentPage = pageList.get(pageList.indexOf(currentPage) + 1);
            contentStream = new PDPageContentStream(pdf, currentPage, PDPageContentStream.AppendMode.APPEND, true, true);
        } else if (templatePdf != null || isOnLastPage()) {
            if (templatePdf != null && pageList.size() == 0) {
                emptyPage = templatePdf.getPage(0);
            } else if (templatePdf != null && templatePdf.getPages().getCount() > 1) {
                COSDictionary dictionary = (COSDictionary) cloneUtility.cloneForNewDocument(templatePdf.getPage(1));
                emptyPage = new PDPage(dictionary);
            } else {
                emptyPage = new PDPage(resource.getPageSize());
            }
            pageList.add(emptyPage);
            pdf.addPage(emptyPage);
            currentPage = emptyPage;
            contentStream = new PDPageContentStream(pdf, currentPage, PDPageContentStream.AppendMode.APPEND, true, true);
        }
    }

    private boolean isOnLastPage() {
        return pageList.indexOf(currentPage) == pageList.size() - 1;
    }

    @Override
    public void checkOpenPages() throws IOException {
        if (!currentPage.equals(pageList.get(0))) {
            contentStream.close();
            currentPage = pageList.get(0);
            contentStream = new PDPageContentStream(pdf, currentPage, PDPageContentStream.AppendMode.APPEND, true, true);
        }
    }

    @Override
    public void drawPageNumber() throws IOException {
        PageNumberRenderer pageNumberRenderer = new PageNumberRenderer();
        pageNumberRenderer.setupRenderer(this, resource);
        pageNumberRenderer.setFormat(resource.getPageNumberFormat());

        for (PDPage page : pageList) {
            contentStream.close();
            contentStream = new PDPageContentStream(pdf, page, PDPageContentStream.AppendMode.APPEND, true, true);
            pageNumberRenderer.renderPageNumber(pageList.indexOf(page) + 1, pageList.size());
        }
    }

    @Override
    public void drawTitleField(PdfField field) throws IOException {
        TitleRenderer titleFieldRenderer = new TitleRenderer();
        titleFieldRenderer.setupRenderer(this, resource);
        titleFieldRenderer.renderLabel(field);
    }

    @Override
    public void drawDataGroupField(PdfField field) throws IOException {
        DataGroupFieldRenderer dataGroupRenderer = new DataGroupFieldRenderer();
        dataGroupRenderer.setupRenderer(this, resource);
        dataGroupRenderer.renderLabel(field);
    }

    @Override
    public void drawTextField(PdfField field) throws IOException {
        TextFieldRenderer textFieldRenderer = new TextFieldRenderer();
        textFieldRenderer.setupRenderer(this, resource);
        int lineCounter = textFieldRenderer.renderLabel(field);
        textFieldRenderer.renderValue(field, lineCounter);
    }

    @Override
    public void drawI18nDividerField(PdfField field) throws IOException {
        I18nDividerFieldRenderer i18nDividerFieldRenderer = new I18nDividerFieldRenderer();
        i18nDividerFieldRenderer.setupRenderer(this, resource);
        i18nDividerFieldRenderer.renderValue(field, 0);
    }

    @Override
    public void drawBooleanField(PdfField field) throws IOException {
        BooleanFieldRenderer booleanFieldRenderer = new BooleanFieldRenderer();
        booleanFieldRenderer.setupRenderer(this, resource);
        int lineCounter = booleanFieldRenderer.renderLabel(field);
        booleanFieldRenderer.renderValue(field, lineCounter);
    }

    @Override
    public void drawEnumerationField(PdfField field) throws IOException {
        EnumerationRenderer enumerationRenderer = new EnumerationRenderer();
        enumerationRenderer.setupRenderer(this, resource);
        int lineCounter = enumerationRenderer.renderLabel(field);
        enumerationRenderer.renderValue(field, lineCounter);
    }

    @Override
    public void drawMultiChoiceField(PdfField field) throws IOException {
        MultiChoiceRenderer multiChoiceRenderer = new MultiChoiceRenderer();
        multiChoiceRenderer.setupRenderer(this, resource);
        int lineCounter = multiChoiceRenderer.renderLabel(field);
        multiChoiceRenderer.renderValue(field, lineCounter);
    }

    @Override
    public void drawBooleanBox(List values, String text, int x, int y) throws IOException {
        if (checkBooleanValue(values, text)) {
            drawSvg(resource.getBooleanChecked(), x, y);
        } else {
            drawSvg(resource.getBooleanUnchecked(), x, y);
        }
    }

    @Override
    public boolean drawSelectionButton(List values, String choice, int x, int y, FieldType fieldType) throws IOException {
        if (values.contains(choice)) {
            if (fieldType == FieldType.MULTICHOICE || fieldType == FieldType.MULTICHOICE_MAP) {
                drawSvg(resource.getCheckboxChecked(), x, y);
            } else if (fieldType == FieldType.ENUMERATION || fieldType == FieldType.ENUMERATION_MAP) {
                drawSvg(resource.getRadioChecked(), x, y);
            }
        } else {
            if (fieldType == FieldType.MULTICHOICE || fieldType == FieldType.MULTICHOICE_MAP) {
                drawSvg(resource.getCheckboxUnchecked(), x, y);
            } else if (fieldType == FieldType.ENUMERATION || fieldType == FieldType.ENUMERATION_MAP) {
                drawSvg(resource.getRadioUnchecked(), x, y);
            }
        }
        return true;
    }

    @Override
    public void drawStroke(int x, int y, int fieldPosY, int width, int lineCounter, float strokeWidth) throws IOException {
        int height = lineHeight * (lineCounter) - padding;
        contentStream.setStrokingColor(Color.LIGHT_GRAY);
        contentStream.setLineWidth(strokeWidth);
        if (fieldPosY >= marginBottom || height > 0) {
            width -= 50;
            y -= 8;
            x += 8;
            contentStream.moveTo(x, y);
            // bottom of rectangle, left to right
            contentStream.lineTo((float) (x + width), y);
            contentStream.curveTo(x + width + 5.9f, y + 0.14f,
                    x + width + 11.06f, y + 5.16f,
                    x + width + 10.96f, y + 10f);

            // right of rectangle, bottom to top
            contentStream.lineTo(x + width + 10.96f, (float) (y + height));
            contentStream.curveTo(x + width + 11.06f, y + height - 5.16f + 10,
                    x + width + 5.9f, y + height + 0.14f + 10,
                    (float) (x + width), y + height + 10f);

            // top of rectangle, right to left
            contentStream.lineTo(x, y + height + 10f);
            contentStream.curveTo(x - 5.9f, y + height + 0.14f + 10,
                    x - 11.06f, y + height - 5.16f + 10,
                    x - 10.96f, (float) (y + height));

            // left of rectangle, top to bottom
            contentStream.lineTo(x - 10.96f, y + 10f);
            contentStream.curveTo(x - 11.06f, y + 5.16f,
                    x - 5.9f, y + 0.14f,
                    x, y);

            contentStream.closePath();
        }
        contentStream.stroke();
    }

    @Override
    public void drawLine(int x, int y, int fieldPosY, int width, int lineCounter, float strokeWidth, Color color) throws IOException {
        contentStream.setStrokingColor(color);
        contentStream.moveTo(x, y);
        contentStream.lineTo((float) (x + width), y);
        contentStream.stroke();
    }

    @Override
    public void writeString(PDType0Font font, int fontSize, int x, int y, String text, Color color) throws IOException {
        contentStream.setFont(font, fontSize);
        contentStream.setNonStrokingColor(color);
        contentStream.beginText();
        contentStream.newLineAtOffset(x, y);
        contentStream.showText(removeUnsupportedChars(text, resource));
        contentStream.endText();
    }

    @Override
    public void writeLabel(PDType0Font font, int fontSize, int x, int y, String text, Color color) throws IOException {
        contentStream.setNonStrokingColor(color != null ? color : Color.GRAY);
        contentStream.setFont(font, fontSize);
        contentStream.beginText();
        contentStream.newLineAtOffset(x, y);
        contentStream.showText(removeUnsupportedChars(text, resource));
        contentStream.endText();
    }

    protected boolean checkBooleanValue(List values, String text) {
        PdfBooleanFormat format = resource.getBooleanFormat();
        if (values.get(0).equals("true")) {
            if (!format.equals(PdfBooleanFormat.SINGLE_BOX_EN) && !format.equals(PdfBooleanFormat.SINGLE_BOX_SK)) {
                return format.getValue().get(0).equals(text);
            } else {
                return true;
            }
        } else if (format.equals(PdfBooleanFormat.DOUBLE_BOX_WITH_TEXT_EN) || format.equals(PdfBooleanFormat.DOUBLE_BOX_WITH_TEXT_SK)) {
            return format.getValue().get(1).equals(text);
        }
        return false;
    }

    protected void drawSvg(PDFormXObject resourceObject, int x, int y) throws IOException {
        contentStream.saveGraphicsState();
        AffineTransform transform = new AffineTransform(boxSize, 0.0F, 0.0F, boxSize, x, y - resource.getBoxPadding());
        contentStream.transform(new Matrix(transform));
        contentStream.drawForm(resourceObject);
        contentStream.restoreGraphicsState();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy