openstitcher.core.PDFRenderer.java Source code

Java tutorial

Introduction

Here is the source code for openstitcher.core.PDFRenderer.java

Source

/**
 * OpenStitcher - A Cross-Stitching Design Program
 * Copyright (C) 2015  OpenStitcher Team
 * -
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * -
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * -
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package openstitcher.core;

import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

import java.awt.Color;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Encapsulates all of the functionality needed to Render a design as a PDF.
 */
public class PDFRenderer {
    public static void render(Design design, String location, ArrayList<LegendEntry> legend)
            throws IOException, COSVisitorException {
        PDDocument document = new PDDocument();
        PDPage page = new PDPage();
        document.addPage(page);
        PDFont font = PDType1Font.HELVETICA;
        PDPageContentStream contentStream = new PDPageContentStream(document, page);

        float pageWidth = page.getMediaBox().getWidth();
        float pageHeight = page.getMediaBox().getHeight();

        float sideMargin = 70.0f;
        float capsMargin = 30.0f;

        // draw the document title
        contentStream.beginText();
        contentStream.setFont(font, 24.0f);
        contentStream.moveTextPositionByAmount(sideMargin, pageHeight - capsMargin - 24.0f);
        contentStream.drawString(design.title);
        contentStream.endText();

        // draw the document author
        contentStream.beginText();
        contentStream.setFont(font, 12.0f);
        contentStream.moveTextPositionByAmount(sideMargin, pageHeight - capsMargin - (24.0f + 12.0f));
        contentStream.drawString(design.author);
        contentStream.endText();

        // draw the document license
        contentStream.beginText();
        contentStream.setFont(font, 12.0f);
        contentStream.moveTextPositionByAmount(sideMargin, pageHeight - capsMargin - (24.0f + 12.0f + 12.0f));
        contentStream.drawString(design.license);
        contentStream.endText();

        // draw the physical size
        contentStream.beginText();
        contentStream.setFont(font, 12.0f);
        contentStream.moveTextPositionByAmount(pageWidth - sideMargin - 100.0f,
                pageHeight - capsMargin - (24.0f + 12.0f + 12.0f));
        contentStream.drawString(design.physicalSize);
        contentStream.endText();

        // draw the pattern
        float gridWidth = pageWidth - (sideMargin * 2);
        float widthPerCell = gridWidth / (float) design.pattern.getPatternWidth();
        float gridStartX = sideMargin;
        float gridStopX = sideMargin + (widthPerCell * design.pattern.getPatternWidth());
        float gridStartY = pageHeight - capsMargin - (24.0f + 12.0f + 12.0f + 12.0f);
        float gridStopY = (pageHeight - capsMargin - (24.0f + 12.0f + 12.0f + 12.0f))
                - (widthPerCell * design.pattern.getPatternHeight());

        // draw the pattern: background
        for (int i = 0; i < design.pattern.getPatternWidth(); i++) {
            for (int j = 0; j < design.pattern.getPatternHeight(); j++) {
                Yarn cellYarn = design.pattern.getPatternCell(i, j);
                if (cellYarn != null) {
                    contentStream.setNonStrokingColor(cellYarn.color);
                    contentStream.fillRect(gridStartX + (widthPerCell * i),
                            gridStartY - (widthPerCell * j) - widthPerCell, widthPerCell, widthPerCell);
                }

            }
        }

        // draw the pattern: grid outline
        contentStream.setStrokingColor(Color.black);
        for (int i = 0; i < design.pattern.getPatternWidth() + 1; i++) {
            // draw vertical lines
            float xCoord = gridStartX + (widthPerCell * i);
            if (i % 5 == 0) {
                contentStream.setLineWidth(2.0f);
            } else {
                contentStream.setLineWidth(1.0f);
            }
            contentStream.drawLine(xCoord, gridStartY, xCoord, gridStopY);
        }
        for (int i = 0; i < design.pattern.getPatternHeight() + 1; i++) {
            // draw horizontal lines
            float yCoord = gridStartY - (widthPerCell * i);
            if (i % 5 == 0) {
                contentStream.setLineWidth(2.0f);
            } else {
                contentStream.setLineWidth(1.0f);
            }
            contentStream.drawLine(gridStartX, yCoord, gridStopX, yCoord);
        }

        // draw the pattern: characters
        contentStream.setNonStrokingColor(Color.black);
        float centeringOffset = widthPerCell / 5.0f;
        for (int i = 0; i < design.pattern.getPatternWidth(); i++) {
            for (int j = 0; j < design.pattern.getPatternHeight(); j++) {
                Yarn cellYarn = design.pattern.getPatternCell(i, j);
                if (cellYarn != null) {
                    int index = LegendEntry.findIndexByYarn(legend, cellYarn);
                    if (index == -1) {
                        throw new RuntimeException("Cell did not exist in legend.");
                    }
                    contentStream.beginText();
                    contentStream.setFont(font, widthPerCell);
                    contentStream.moveTextPositionByAmount(gridStartX + (widthPerCell * i) + centeringOffset,
                            gridStartY - (widthPerCell * j) - widthPerCell + centeringOffset);
                    contentStream.drawString(legend.get(index).character);
                    contentStream.endText();
                }
            }
        }

        // draw the legend
        float legendWidth = pageWidth - (sideMargin * 2);
        float widthPerLegendCell = legendWidth / (float) legend.size();
        float legendStartX = sideMargin;
        float legendStopX = pageWidth - sideMargin;
        float legendStartY = capsMargin + 12.0f;
        float legendStopY = capsMargin;
        float legendCellPadding = 1.0f;
        float exampleCellWidth = 10.0f;

        for (int i = 0; i < legend.size(); i++) {
            // draw box
            contentStream.setNonStrokingColor(legend.get(i).yarn.color);
            contentStream.fillRect(legendStartX + legendCellPadding + (i * widthPerLegendCell),
                    legendStopY + legendCellPadding, exampleCellWidth, exampleCellWidth);

            // draw character
            contentStream.beginText();
            contentStream.setNonStrokingColor(legend.get(i).fontColor);
            contentStream.setFont(font, 10.0f);
            contentStream.moveTextPositionByAmount(legendStartX + legendCellPadding + (i * widthPerLegendCell),
                    legendStopY + legendCellPadding);
            contentStream.drawString(legend.get(i).character);
            contentStream.endText();

            // draw yarn name
            contentStream.beginText();
            contentStream.setNonStrokingColor(Color.black);
            contentStream.setFont(font, 10.0f);
            contentStream.moveTextPositionByAmount(legendStartX + legendCellPadding + exampleCellWidth
                    + legendCellPadding + (i * widthPerLegendCell), legendStopY + legendCellPadding);
            contentStream.drawString(legend.get(i).yarn.name);
            contentStream.endText();
        }

        contentStream.close();
        document.save(location);
        document.close();
    }

}