PDFBox: рисовать миллиметровую бумагу - PullRequest
0 голосов
/ 22 января 2020

Я хочу нарисовать миллиметровую бумагу в формате PDF, но когда я измеряю напечатанный документ, я немного не в форме (нарисовано см <1 см). Я использую размер бумаги формата A4 (210 * 297), а также pageWidth и pageHeight, чтобы вычислить количество пикселей на мм (использовалось среднее значение для обоих, надеясь, что это сработает). Я также пробовал другой вариант при печати документа (с полем & без поля и т. Д. c.), Но это также не сработало. </p>

public class TestPrint extends Application {

    protected static final float DINA4_IN_MM_WIDTH = 210;
    protected static final float DINA4_IN_MM_HEIGHT = 297;
    protected static final int LEFTSIDE = 35;
    protected static final int TEXT_FONT_SIZE = 11;
    protected static final int TOP_MARGIN = 60;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        File file = new File("test.pdf");
        double windowWidth = 600;
        double windowHeight = 1000;
        float x = LEFTSIDE;

        PDFont font = PDType1Font.TIMES_ROMAN;
        PDPage page = new PDPage(PDRectangle.A4);
        PDRectangle pageSize = page.getMediaBox();
        PDDocument mainDocument = new PDDocument();
        mainDocument.addPage(page);

        float stringHeight = font.getFontDescriptor().getFontBoundingBox().getHeight() * TEXT_FONT_SIZE;
        float y = pageSize.getHeight() - stringHeight / 1000f - TOP_MARGIN;
        float pixelPerMM = (pageSize.getWidth() / DINA4_IN_MM_WIDTH + pageSize.getHeight() / DINA4_IN_MM_HEIGHT) / 2;
        float displayW = 520;
        float displayH = 300;
        try {
            PDPageContentStream contents = new PDPageContentStream(mainDocument, page, AppendMode.APPEND, true);
            drawBackgroundRaster(contents, x, y, displayW, displayH, pixelPerMM);
            contents.close();
            mainDocument.save(file);

            ImageView imgView = getImageViewFromDocument(mainDocument, windowHeight);
            VBox vBox = new VBox(imgView);
            Scene scene = new Scene(vBox, windowWidth, windowHeight);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // draw millimeter paper with dots, two boxes shall be 1cm
    private void drawBackgroundRaster(PDPageContentStream contents, float x, float y, float displayW, float displayH,
            float pixelPerMM) throws IOException {
        // rasterColor = grey
        Color rasterColor = new Color(175, 175, 175);
        contents.setStrokingColor(rasterColor);
        float dotSize = 0.5f;
        // draw vertical lines
        for (int i = 0; i <= displayW; i++) {
            float xPos = x + i * pixelPerMM;
            if (xPos > displayW + x) {
                break;
            }
            contents.moveTo(xPos, y);
            if (i % 5 == 0) {
                contents.setLineDashPattern(new float[] {}, 0);
                contents.lineTo(xPos, y - displayH);
            }
            contents.stroke();
        }
        // draw dots and horizontal lines
        for (int i = 0; i <= displayH; i++) {
            float yPos = y - i * pixelPerMM;
            if (yPos < y - displayH) {
                break;
            }
            contents.moveTo(x, yPos);
            if (i % 5 == 0) {
                contents.setLineDashPattern(new float[] {}, 0);
                contents.lineTo(x + displayW, yPos);
            } else {
                contents.setLineDashPattern(new float[] { dotSize, pixelPerMM - dotSize }, dotSize / 2);
                contents.lineTo(x + displayW, yPos);
            }
            contents.stroke();
        }
        contents.setLineDashPattern(new float[] {}, 0);

        contents.moveTo(x, y);
        contents.lineTo(x + displayW, y);
        contents.lineTo(x + displayW, y - displayH);
        contents.lineTo(x, y - displayH);
        contents.lineTo(x, y);
        contents.stroke();
    }

    private ImageView getImageViewFromDocument(PDDocument mainDocument, double windowHeight) throws IOException {
        PDFRenderer pdfRenderer = new PDFRenderer(mainDocument);
        BufferedImage bim = pdfRenderer.renderImageWithDPI(0, 150, ImageType.RGB);
        Image image = SwingFXUtils.toFXImage(bim, null);
        ImageView imageView = new ImageView(image);
        double scaleFactor = windowHeight / imageView.getImage().getHeight();
        double zoomFactor = scaleFactor * 2d * 2.55d / 3;
        double width = imageView.getImage().getWidth() * zoomFactor;
        double height = imageView.getImage().getHeight() * zoomFactor;
        imageView.setFitWidth(width);
        imageView.setFitHeight(height);
        return imageView;
    }
}
...