private void exportGraphToPdf(mxGraph graph, String filename) { Rectangle bounds = new Rectangle(trackScheme.getGUI().graphComponent.getViewport().getViewSize()); // step 1 com.itextpdf.text.Rectangle pageSize = new com.itextpdf.text.Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); com.itextpdf.text.Document document = new com.itextpdf.text.Document(pageSize); // step 2 PdfWriter writer = null; Graphics2D g2 = null; try { writer = PdfWriter.getInstance(document, new FileOutputStream(filename)); // step 3 document.open(); // step 4 PdfContentByte canvas = writer.getDirectContent(); g2 = canvas.createGraphics(pageSize.getWidth(), pageSize.getHeight()); trackScheme.getGUI().graphComponent.getViewport().paintComponents(g2); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } finally { g2.dispose(); document.close(); } }
private static void booklet(String input) throws Exception { String output = input.replace(".pdf", "-booklet.pdf"); PdfReader reader = new PdfReader(input); int n = reader.getNumberOfPages(); Rectangle pageSize = reader.getPageSize(1); System.out.println("Input page size: " + pageSize); Document doc = new Document(PageSize.A4.rotate(), 0, 0, 0, 0); PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(output)); doc.open(); splitLine(doc, writer); int[] pages = new int[(n + 3) / 4 * 4]; int x = 1, y = pages.length; for (int i = 0; i < pages.length; ) { pages[i++] = y--; pages[i++] = x++; pages[i++] = x++; pages[i++] = y--; } PdfContentByte cb = writer.getDirectContent(); float bottom = (doc.top() - pageSize.getHeight()) / 2 + kOffset; float left = doc.right() / 2 - (pageSize.getWidth() + kTextWidth) / 2 - kMargin; float right = doc.right() / 2 - (pageSize.getWidth() - kTextWidth) / 2 + kMargin; for (int i = 0; i < pages.length; ) { PdfImportedPage page = getPage(writer, reader, pages[i++]); if (page != null) cb.addTemplate(page, left, bottom); page = getPage(writer, reader, pages[i++]); if (page != null) cb.addTemplate(page, right, bottom); doc.newPage(); } doc.close(); }
public static float fitText( Font font, String text, Rectangle rect, float maxFontSize, boolean newlinesAllowed) { float minFontSize = 1f; float potentialFontSize; while (true) { potentialFontSize = (maxFontSize + minFontSize) / 2.0f; font.setSize(potentialFontSize); LinkedList<Chunk> lineChunks = splitScrambleToLineChunks(text, font, rect.getWidth()); if (!newlinesAllowed && lineChunks.size() > 1) { // If newlines are not allowed, and we had to split the text into more than // one line, then potentialFontSize is too large. maxFontSize = potentialFontSize; } else { // The font size seems to be a pretty good estimate for how // much vertical space a row actually takes up. float totalHeight = lineChunks.size() * potentialFontSize; if (totalHeight < rect.getHeight()) { minFontSize = potentialFontSize; } else { maxFontSize = potentialFontSize; } } if (maxFontSize - minFontSize < FITTEXT_FONTSIZE_PRECISION) { // Err on the side of too small, because being too large will screw up // layout. potentialFontSize = minFontSize; break; } } return potentialFontSize; }
/** * Gets the Y value for centering the watermark image * * @param r rectangle * @param img image * @return */ protected static float getCenterY(final Rectangle r, final Image img) { float y = 0; final float pdfheight = r.getHeight(); final float imgheight = img.getHeight(); y = (pdfheight - imgheight) / 2; return y; }
private static void crop(String input) throws Exception { String output = input.replace(".pdf", "-crop.pdf"); PdfReader reader = new PdfReader(input); final int n = reader.getNumberOfPages(); Rectangle pageSize = reader.getPageSize(1); System.out.println("Input page size: " + pageSize); float left = (pageSize.getWidth() - kTextWidth) / 2 - kMargin; float right = pageSize.getWidth() - left; float bottom = (pageSize.getHeight() - kTextHeight) / 2; float top = pageSize.getHeight() - bottom; PdfRectangle rect = new PdfRectangle(left, bottom + kOffset, right, top + kOffset); for (int i = 1; i <= n; i++) { PdfDictionary pageDict = reader.getPageN(i); pageDict.put(PdfName.CROPBOX, rect); } PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(output)); stamper.close(); }
public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvas) { PdfContentByte cb = canvas[PdfPTable.BACKGROUNDCANVAS]; cb.roundRectangle( rect.getLeft() + 1.5f, rect.getBottom() + 1.5f, rect.getWidth() - 3, rect.getHeight() - 3, 4); cb.setCMYKColorFill(0x00, 0x00, 0x00, 0x00); cb.fill(); }
public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvas) { PdfContentByte cb = canvas[PdfPTable.LINECANVAS]; cb.roundRectangle( rect.getLeft() + 1.5f, rect.getBottom() + 1.5f, rect.getWidth() - 3, rect.getHeight() - 3, 4); cb.setLineWidth(1.5f); cb.setCMYKColorStrokeF(color[0], color[1], color[2], color[3]); cb.stroke(); }
/** * Draws the info about the movie. * * @throws DocumentException */ protected void drawMovieInfo(Screening screening, PdfContentByte directcontent) throws DocumentException { if (screening.isPress()) { Rectangle rect = getPosition(screening); ColumnText.showTextAligned( directcontent, Element.ALIGN_CENTER, press, (rect.getLeft() + rect.getRight()) / 2, rect.getBottom() + rect.getHeight() / 4, 0); } }
public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) { try { PdfContentByte cb = canvases[PdfPTable.BACKGROUNDCANVAS]; PdfPatternPainter patternPainter = cb.createPattern(image.getScaledWidth(), image.getScaledHeight()); image.setAbsolutePosition(0, 0); patternPainter.addImage(image); cb.saveState(); cb.setPatternFill(patternPainter); cb.rectangle( position.getLeft(), position.getBottom(), position.getWidth(), position.getHeight()); cb.fill(); cb.restoreState(); } catch (DocumentException e) { throw new ExceptionConverter(e); } }
/** * Create a pushbutton for a key * * @param writer the PdfWriter * @param rect the position of the key * @param btn the label for the key * @param script the script to be executed when the button is pushed */ public void addPushButton(PdfWriter writer, Rectangle rect, String btn, String script) { float w = rect.getWidth(); float h = rect.getHeight(); PdfFormField pushbutton = PdfFormField.createPushButton(writer); pushbutton.setFieldName("btn_" + btn); pushbutton.setWidget(rect, PdfAnnotation.HIGHLIGHT_PUSH); PdfContentByte cb = writer.getDirectContent(); pushbutton.setAppearance( PdfAnnotation.APPEARANCE_NORMAL, createAppearance(cb, btn, BaseColor.GRAY, w, h)); pushbutton.setAppearance( PdfAnnotation.APPEARANCE_ROLLOVER, createAppearance(cb, btn, BaseColor.RED, w, h)); pushbutton.setAppearance( PdfAnnotation.APPEARANCE_DOWN, createAppearance(cb, btn, BaseColor.BLUE, w, h)); pushbutton.setAdditionalActions(PdfName.U, PdfAction.javaScript(script, writer)); pushbutton.setAdditionalActions( PdfName.E, PdfAction.javaScript("this.showMove('" + btn + "');", writer)); pushbutton.setAdditionalActions(PdfName.X, PdfAction.javaScript("this.showMove(' ');", writer)); writer.addAnnotation(pushbutton); }
public PDFRenderTargetImpl( PdfContentByte cb, double width, double height, double topLeftX, double topLeftY, Rectangle size, float marginLeft, float marginRight, float marginTop, float marginBottom, boolean landscape) { this.cb = cb; this.marginTop = marginTop; this.marginLeft = marginLeft; this.marginBottom = marginBottom; this.marginRight = marginRight; this.pageSize = size; this.landscape = landscape; double centerX = topLeftX + width / 2; double centerY = topLeftY + height / 2; // Transform double pageWidth = size.getWidth() - marginLeft - marginRight; double pageHeight = size.getHeight() - marginTop - marginBottom; double ratioWidth = pageWidth / width; double ratioHeight = pageHeight / height; double scale = (float) (ratioWidth < ratioHeight ? ratioWidth : ratioHeight); double translateX = (marginLeft + pageWidth / 2.) / scale; double translateY = (marginBottom + pageHeight / 2.) / scale; cb.transform(AffineTransform.getTranslateInstance(-centerX * scale, centerY * scale)); cb.transform(AffineTransform.getScaleInstance(scale, scale)); cb.transform(AffineTransform.getTranslateInstance(translateX, translateY)); FontFactory.register("/org/gephi/preview/fonts/LiberationSans.ttf", "ArialMT"); }
/** * Create a rectangle for the visible signature using the selected position and signature size * * @param position * @param width * @param height * @return */ private static Rectangle positionSignature( final String position, final Rectangle pageRect, final int width, final int height, final int marginX, final int marginY) { final float pageHeight = pageRect.getHeight(); final float pageWidth = pageRect.getWidth(); Rectangle r = null; if (position.equals(DigitalSigningDTO.POSITION_BOTTOMLEFT)) { r = new Rectangle(marginX, marginY, width + marginX, height + marginY); } else if (position.equals(DigitalSigningDTO.POSITION_BOTTOMRIGHT)) { r = new Rectangle( pageWidth - width - marginX, height + marginY, pageWidth - marginX, marginY); } else if (position.equals(DigitalSigningDTO.POSITION_TOPLEFT)) { r = new Rectangle( marginX, pageHeight - marginY, width + marginX, pageHeight - height - marginY); } else if (position.equals(DigitalSigningDTO.POSITION_TOPRIGHT)) { r = new Rectangle( pageWidth - width - marginX, pageHeight - marginY, pageWidth - marginX, pageHeight - height - marginY); } else if (position.equals(DigitalSigningDTO.POSITION_CENTER)) { r = new Rectangle( (pageWidth / 2) - (width / 2), (pageHeight / 2) - (height / 2), (pageWidth / 2) + (width / 2), (pageHeight / 2) + (height / 2)); } return r; }
private static void addScrambles( PdfWriter docWriter, Document doc, ScrambleRequest scrambleRequest, String globalTitle) throws DocumentException, IOException { if (scrambleRequest.fmc) { Rectangle pageSize = doc.getPageSize(); for (int i = 0; i < scrambleRequest.scrambles.length; i++) { String scramble = scrambleRequest.scrambles[i]; PdfContentByte cb = docWriter.getDirectContent(); float LINE_THICKNESS = 0.5f; BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); int bottom = 30; int left = 35; int right = (int) (pageSize.getWidth() - left); int top = (int) (pageSize.getHeight() - bottom); int height = top - bottom; int width = right - left; int solutionBorderTop = bottom + (int) (height * .5); int scrambleBorderTop = solutionBorderTop + 40; int competitorInfoBottom = top - (int) (height * .15); int gradeBottom = competitorInfoBottom - 50; int competitorInfoLeft = right - (int) (width * .45); int rulesRight = competitorInfoLeft; int padding = 5; // Outer border cb.setLineWidth(2f); cb.moveTo(left, top); cb.lineTo(left, bottom); cb.lineTo(right, bottom); cb.lineTo(right, top); // Solution border cb.moveTo(left, solutionBorderTop); cb.lineTo(right, solutionBorderTop); // Rules bottom border cb.moveTo(left, scrambleBorderTop); cb.lineTo(rulesRight, scrambleBorderTop); // Rules right border cb.lineTo(rulesRight, gradeBottom); // Grade bottom border cb.moveTo(competitorInfoLeft, gradeBottom); cb.lineTo(right, gradeBottom); // Competitor info bottom border cb.moveTo(competitorInfoLeft, competitorInfoBottom); cb.lineTo(right, competitorInfoBottom); // Competitor info left border cb.moveTo(competitorInfoLeft, gradeBottom); cb.lineTo(competitorInfoLeft, top); // Solution lines int availableSolutionWidth = right - left; int availableSolutionHeight = scrambleBorderTop - bottom; int lineWidth = 25; // int linesX = (availableSolutionWidth/lineWidth + 1)/2; int linesX = 10; int linesY = (int) Math.ceil(1.0 * WCA_MAX_MOVES_FMC / linesX); cb.setLineWidth(LINE_THICKNESS); cb.stroke(); // int allocatedX = (2*linesX-1)*lineWidth; int excessX = availableSolutionWidth - linesX * lineWidth; int moveCount = 0; solutionLines: for (int y = 0; y < linesY; y++) { for (int x = 0; x < linesX; x++) { if (moveCount >= WCA_MAX_MOVES_FMC) { break solutionLines; } int xPos = left + x * lineWidth + (x + 1) * excessX / (linesX + 1); int yPos = solutionBorderTop - (y + 1) * availableSolutionHeight / (linesY + 1); cb.moveTo(xPos, yPos); cb.lineTo(xPos + lineWidth, yPos); moveCount++; } } float UNDERLINE_THICKNESS = 0.2f; cb.setLineWidth(UNDERLINE_THICKNESS); cb.stroke(); cb.beginText(); int availableScrambleSpace = right - left - 2 * padding; int scrambleFontSize = 20; String scrambleStr = "Scramble: " + scramble; float scrambleWidth; do { scrambleFontSize--; scrambleWidth = bf.getWidthPoint(scrambleStr, scrambleFontSize); } while (scrambleWidth > availableScrambleSpace); cb.setFontAndSize(bf, scrambleFontSize); int scrambleY = 3 + solutionBorderTop + (scrambleBorderTop - solutionBorderTop - scrambleFontSize) / 2; cb.showTextAligned(PdfContentByte.ALIGN_LEFT, scrambleStr, left + padding, scrambleY, 0); cb.endText(); int availableScrambleWidth = right - rulesRight; int availableScrambleHeight = gradeBottom - scrambleBorderTop; Dimension dim = scrambleRequest.scrambler.getPreferredSize( availableScrambleWidth - 2, availableScrambleHeight - 2); PdfTemplate tp = cb.createTemplate(dim.width, dim.height); Graphics2D g2 = new PdfGraphics2D(tp, dim.width, dim.height, new DefaultFontMapper()); try { Svg svg = scrambleRequest.scrambler.drawScramble(scramble, scrambleRequest.colorScheme); drawSvgToGraphics2D(svg, g2, dim); } catch (InvalidScrambleException e) { l.log(Level.INFO, "", e); } finally { g2.dispose(); } cb.addImage( Image.getInstance(tp), dim.width, 0, 0, dim.height, rulesRight + (availableScrambleWidth - dim.width) / 2, scrambleBorderTop + (availableScrambleHeight - dim.height) / 2); ColumnText ct = new ColumnText(cb); int fontSize = 15; int marginBottom = 10; int offsetTop = 27; boolean showScrambleCount = scrambleRequest.scrambles.length > 1; if (showScrambleCount) { offsetTop -= fontSize + 2; } cb.beginText(); cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_CENTER, globalTitle, competitorInfoLeft + (right - competitorInfoLeft) / 2, top - offsetTop, 0); offsetTop += fontSize + 2; cb.endText(); cb.beginText(); cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_CENTER, scrambleRequest.title, competitorInfoLeft + (right - competitorInfoLeft) / 2, top - offsetTop, 0); cb.endText(); if (showScrambleCount) { cb.beginText(); offsetTop += fontSize + 2; cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_CENTER, "Scramble " + (i + 1) + " of " + scrambleRequest.scrambles.length, competitorInfoLeft + (right - competitorInfoLeft) / 2, top - offsetTop, 0); cb.endText(); } offsetTop += fontSize + marginBottom; cb.beginText(); fontSize = 15; cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_LEFT, "Competitor: __________________", competitorInfoLeft + padding, top - offsetTop, 0); offsetTop += fontSize + marginBottom; cb.endText(); cb.beginText(); fontSize = 15; cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_LEFT, "WCA ID:", competitorInfoLeft + padding, top - offsetTop, 0); cb.setFontAndSize(bf, 19); int wcaIdLength = 63; cb.showTextAligned( PdfContentByte.ALIGN_LEFT, "_ _ _ _ _ _ _ _ _ _", competitorInfoLeft + padding + wcaIdLength, top - offsetTop, 0); offsetTop += fontSize + (int) (marginBottom * 1.8); cb.endText(); cb.beginText(); fontSize = 11; cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_CENTER, "DO NOT FILL IF YOU ARE THE COMPETITOR", competitorInfoLeft + (right - competitorInfoLeft) / 2, top - offsetTop, 0); offsetTop += fontSize + marginBottom; cb.endText(); cb.beginText(); fontSize = 11; cb.setFontAndSize(bf, fontSize); cb.showTextAligned( PdfContentByte.ALIGN_CENTER, "Graded by: _______________ Result: ______", competitorInfoLeft + (right - competitorInfoLeft) / 2, top - offsetTop, 0); offsetTop += fontSize + marginBottom; cb.endText(); cb.beginText(); cb.setFontAndSize(bf, 25f); int MAGIC_NUMBER = 40; // kill me now cb.showTextAligned( PdfContentByte.ALIGN_CENTER, "Fewest Moves", left + (competitorInfoLeft - left) / 2, top - MAGIC_NUMBER, 0); cb.endText(); com.itextpdf.text.List rules = new com.itextpdf.text.List(com.itextpdf.text.List.UNORDERED); rules.add("Notate your solution by writing one move per bar."); rules.add("To delete moves, clearly erase/blacken them."); rules.add("Face moves F, B, R, L, U, and D are clockwise."); rules.add("Rotations x, y, and z follow R, U, and F."); rules.add("' inverts a move; 2 doubles a move. (e.g.: U', U2)"); rules.add("w makes a face move into two layers. (e.g.: Uw)"); rules.add("A [lowercase] move is a cube rotation. (e.g.: [u])"); ct.addElement(rules); int rulesTop = competitorInfoBottom + 55; ct.setSimpleColumn( left + padding, scrambleBorderTop, competitorInfoLeft - padding, rulesTop, 0, Element.ALIGN_LEFT); ct.go(); rules = new com.itextpdf.text.List(com.itextpdf.text.List.UNORDERED); rules.add("You have 1 hour to find a solution."); rules.add("Your solution length will be counted in OBTM."); int maxMoves = WCA_MAX_MOVES_FMC; rules.add("Your solution must be at most " + maxMoves + " moves, including rotations."); rules.add( "Your solution must not be directly derived from any part of the scrambling algorithm."); ct.addElement(rules); MAGIC_NUMBER = 150; // kill me now ct.setSimpleColumn( left + padding, scrambleBorderTop, rulesRight - padding, rulesTop - MAGIC_NUMBER, 0, Element.ALIGN_LEFT); ct.go(); doc.newPage(); } } else { Rectangle pageSize = doc.getPageSize(); float sideMargins = 100 + doc.leftMargin() + doc.rightMargin(); float availableWidth = pageSize.getWidth() - sideMargins; float vertMargins = doc.topMargin() + doc.bottomMargin(); float availableHeight = pageSize.getHeight() - vertMargins; if (scrambleRequest.extraScrambles.length > 0) { availableHeight -= 20; // Yeee magic numbers. This should make space for the headerTable. } int scramblesPerPage = Math.min(MAX_SCRAMBLES_PER_PAGE, scrambleRequest.getAllScrambles().size()); int maxScrambleImageHeight = (int) (availableHeight / scramblesPerPage - 2 * SCRAMBLE_IMAGE_PADDING); int maxScrambleImageWidth = (int) (availableWidth / 2); // We don't let scramble images take up more than half the page if (scrambleRequest.scrambler.getShortName().equals("minx")) { // TODO - If we allow the megaminx image to be too wide, the // megaminx scrambles get really tiny. This tweak allocates // a more optimal amount of space to the scrambles. This is possible // because the scrambles are so uniformly sized. maxScrambleImageWidth = 190; } Dimension scrambleImageSize = scrambleRequest.scrambler.getPreferredSize(maxScrambleImageWidth, maxScrambleImageHeight); // First do a dry run just to see if any scrambles require highlighting. // Then do the real run, and force highlighting on every scramble // if any scramble required it. boolean forceHighlighting = false; for (boolean dryRun : new boolean[] {true, false}) { String scrambleNumberPrefix = ""; TableAndHighlighting tableAndHighlighting = createTable( docWriter, doc, sideMargins, scrambleImageSize, scrambleRequest.scrambles, scrambleRequest.scrambler, scrambleRequest.colorScheme, scrambleNumberPrefix, forceHighlighting); if (dryRun) { if (tableAndHighlighting.highlighting) { forceHighlighting = true; continue; } } else { doc.add(tableAndHighlighting.table); } if (scrambleRequest.extraScrambles.length > 0) { PdfPTable headerTable = new PdfPTable(1); headerTable.setTotalWidth(new float[] {availableWidth}); headerTable.setLockedWidth(true); PdfPCell extraScramblesHeader = new PdfPCell(new Paragraph("Extra scrambles")); extraScramblesHeader.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); extraScramblesHeader.setPaddingBottom(3); headerTable.addCell(extraScramblesHeader); if (!dryRun) { doc.add(headerTable); } scrambleNumberPrefix = "E"; TableAndHighlighting extraTableAndHighlighting = createTable( docWriter, doc, sideMargins, scrambleImageSize, scrambleRequest.extraScrambles, scrambleRequest.scrambler, scrambleRequest.colorScheme, scrambleNumberPrefix, forceHighlighting); if (dryRun) { if (tableAndHighlighting.highlighting) { forceHighlighting = true; continue; } } else { doc.add(extraTableAndHighlighting.table); } } } } doc.newPage(); }
private static PdfReader createPdf( String globalTitle, Date creationDate, ScrambleRequest scrambleRequest) throws DocumentException, IOException { azzert(scrambleRequest.scrambles.length > 0); ByteArrayOutputStream pdfOut = new ByteArrayOutputStream(); Rectangle pageSize = PageSize.LETTER; Document doc = new Document(pageSize, 0, 0, 75, 75); PdfWriter docWriter = PdfWriter.getInstance(doc, pdfOut); docWriter.setBoxSize( "art", new Rectangle(36, 54, pageSize.getWidth() - 36, pageSize.getHeight() - 54)); doc.addCreationDate(); doc.addProducer(); if (globalTitle != null) { doc.addTitle(globalTitle); } doc.open(); // Note that we ignore scrambleRequest.copies here. addScrambles(docWriter, doc, scrambleRequest, globalTitle); doc.close(); // TODO - is there a better way to convert from a PdfWriter to a PdfReader? PdfReader pr = new PdfReader(pdfOut.toByteArray()); if (scrambleRequest.fmc) { // We don't watermark the FMC sheets because they already have // the competition name on them. return pr; } pdfOut = new ByteArrayOutputStream(); doc = new Document(pageSize, 0, 0, 75, 75); docWriter = PdfWriter.getInstance(doc, pdfOut); doc.open(); PdfContentByte cb = docWriter.getDirectContent(); for (int pageN = 1; pageN <= pr.getNumberOfPages(); pageN++) { PdfImportedPage page = docWriter.getImportedPage(pr, pageN); doc.newPage(); cb.addTemplate(page, 0, 0); Rectangle rect = pr.getBoxSize(pageN, "art"); // Header ColumnText.showTextAligned( cb, Element.ALIGN_LEFT, new Phrase(Utils.SDF.format(creationDate)), rect.getLeft(), rect.getTop(), 0); ColumnText.showTextAligned( cb, Element.ALIGN_CENTER, new Phrase(globalTitle), (pageSize.getLeft() + pageSize.getRight()) / 2, pageSize.getTop() - 60, 0); ColumnText.showTextAligned( cb, Element.ALIGN_CENTER, new Phrase(scrambleRequest.title), (pageSize.getLeft() + pageSize.getRight()) / 2, pageSize.getTop() - 45, 0); if (pr.getNumberOfPages() > 1) { ColumnText.showTextAligned( cb, Element.ALIGN_RIGHT, new Phrase(pageN + "/" + pr.getNumberOfPages()), rect.getRight(), rect.getTop(), 0); } // Footer String generatedBy = "Generated by " + Utils.getProjectName() + "-" + Utils.getVersion(); ColumnText.showTextAligned( cb, Element.ALIGN_CENTER, new Phrase(generatedBy), (pageSize.getLeft() + pageSize.getRight()) / 2, pageSize.getBottom() + 40, 0); } doc.close(); // TODO - is there a better way to convert from a PdfWriter to a PdfReader? pr = new PdfReader(pdfOut.toByteArray()); return pr; // The PdfStamper class doesn't seem to be working. // pdfOut = new ByteArrayOutputStream(); // PdfStamper ps = new PdfStamper(pr, pdfOut); // // for(int pageN = 1; pageN <= pr.getNumberOfPages(); pageN++) { // PdfContentByte pb = ps.getUnderContent(pageN); // Rectangle rect = pr.getBoxSize(pageN, "art"); // System.out.println(rect.getLeft()); // System.out.println(rect.getWidth()); // ColumnText.showTextAligned(pb, // Element.ALIGN_LEFT, new Phrase("Hello people!"), 36, 540, 0); //// ColumnText.showTextAligned(pb, //// Element.ALIGN_CENTER, new Phrase("HELLO WORLD"), //// (rect.getLeft() + rect.getRight()) / 2, rect.getTop(), 0); // } // ps.close(); // return ps.getReader(); }