@Override public void onEndPage(PdfWriter writer, Document document) { // This scales the image to the page, // use the image's width & height if you don't want to scale. float width = document.getPageSize().getWidth(); float height = document.getPageSize().getHeight(); try { Image background = Image.getInstance("e:/upload/toys/makbuz.jpg"); writer.getDirectContentUnder().addImage(background, width, 0, 0, height, 0, 0); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
public void process(ObjectIO input, ObjectIO output) { try { // OJO pasarle el idemisor String idemisor = "1"; recuperaInput(input); Rectangle pageSize = new Rectangle(PageSize.A4); // pageSize.setBackgroundColor(Color.TRANSLUCENT); pageSize.rotate(); documento = new Document(pageSize); System.out.println("WIDTH " + documento.getPageSize().getWidth()); System.out.println("HEIGHT " + documento.getPageSize().getHeight()); namefile = "BarCode_" + idemisor + "_codigoBARRAS.pdf"; filecrea = "C://DATOS//LRA//tmp//" + namefile; // filecrea = PropiedadesJLet.getInstance().getProperty("path.gen.recibo") +"emisor_"+ // idemisor +"/"+ namefile; System.out.println( "***************************Se va a crear este codigo de barras: " + filecrea); writer = PdfWriter.getInstance(documento, new FileOutputStream(filecrea)); documento.open(); pintaCodigoBarras(); absText(writer, texto1xx, xpostex1, ypostex1, 8); absText(writer, texto2xx, xpostex2, ypostex2, 8); try { output.setValue("idemisor", idemisor); output.setValue("filecrea", namefile); output.setValue("txmensaj", "Generacion Ok - "); } catch (Exception e) { e.printStackTrace(); } } catch (DocumentException de) { System.err.println(de.getMessage()); } catch (IOException ioe) { System.err.println(ioe.getMessage()); } finally { documento.close(); } }
// ---------------- for footer and header....------------------ @Override public void onEndPage(PdfWriter writer, Document document) { try { Rectangle page = document.getPageSize(); // we will print the header using the code below PdfPTable headTable = getHeader(); headTable.setTotalWidth(page.getWidth() - document.leftMargin() - document.rightMargin()); // the table is printed at the spcific location headTable.writeSelectedRows(0, -1, document.leftMargin(), 830, writer.getDirectContent()); // we will print the footer using the code below PdfPTable footTable = getFooter(); footTable.setTotalWidth(page.getWidth() - document.leftMargin() - document.rightMargin()); footTable.writeSelectedRows( 0, -1, document.leftMargin(), document.bottomMargin() - 560, writer.getDirectContent()); } catch (Exception ex) { ex.printStackTrace(); } // TODO Auto-generated method stub }
/** * Calculates the maximum font size, which will fits all characters of the given fileContent into * the document's page width. * * @param document where the text will be inputed. * @param fileContent the content of the file the will be written. * @param fontName the name of the font which will be used while writing into a file. * @param encoding the encoding which will be used while writing into a file. * @return the max size of the font that will fit the string into the given document's page width. * @throws IOException * @throws DocumentException */ public static float calculateFontSizeFittingAllStringIntoPageWidth( Document document, String fileContent, String fontName, String encoding) throws IOException, DocumentException { String longestLineOfParagraph = ""; String newLineMarker = System.getProperty("line.separator"); String[] lineArray = fileContent.split(newLineMarker); // System.out.println("lineArray.length="+lineArray.length); for (int i = 0; i < lineArray.length; i++) { String line = lineArray[i]; if (longestLineOfParagraph.length() < line.length()) longestLineOfParagraph = line; } // Round margins' size up... int marignLeft = (int) (document.leftMargin() + 1); int marginRight = (int) (document.rightMargin() + 1); // round page width down... int pageWidth = (int) document.getPageSize().getWidth(); // ...to make sure we have correct max space for text. int maxSpaceForText = pageWidth - marignLeft - marginRight; System.out.println( "marignLeft=" + marignLeft + "; marginRight=" + marginRight + "; pageWidth=" + pageWidth + "; maxSpaceForText=" + maxSpaceForText); float fontSize = 12.0f; BaseFont bf = BaseFont.createFont(fontName, encoding, BaseFont.EMBEDDED); float textWidthForFontSize = bf.getWidthPointKerned(longestLineOfParagraph, fontSize); float requiredFontSize = (fontSize * maxSpaceForText) / textWidthForFontSize; return requiredFontSize; }
public void pintaCodigoBarras() { Image imageLogo; Image imageBarc = null; String imageUrl; Font fuente = new Font(FontFamily.HELVETICA, 8, Font.NORMAL, new BaseColor(64, 64, 64)); BaseColor bkcolor = new BaseColor(255, 255, 255); try { PdfPTable table = new PdfPTable(new float[] {1, 1, 1, 1, 1}); // table.setTotalWidth(900); table.getDefaultCell().setBorder(0); // imageUrl = PropiedadesJLet.getInstance().getProperty("path.img.logos") + // "logo_recibos.png"; // imageLogo = Image.getInstance(imageUrl); int yinic = 805; int xinic = 0; int posicion = 0; // posicion donde comenzara a imprimir // for (int i = 0; i < listcode.size(); i++){ String codeunic = codvalue; // System.out.println(codeunic.substring(0,5) +"-"+ codeunic.substring(6,7)); imageBarc = getBarcode(documento, writer, codeunic); PdfPTable tablein = new PdfPTable(new float[] {1f, 3f, 1f}); tablein.getDefaultCell().setBorder(0); tablein.setTotalWidth(documento.getPageSize().getWidth()); tablein.addCell(FRAparen.getCelda(" ", fuente, bkcolor, "center")).setBorder(0); // tablein.addCell(imageLogo); tablein.addCell(FRAparen.getCelda(" ", fuente, bkcolor, "center")).setBorder(0); tablein.addCell(FRAparen.getCelda(" ", fuente, bkcolor, "center")).setBorder(0); tablein.addCell(imageBarc); tablein.addCell(FRAparen.getCelda(" ", fuente, bkcolor, "center")).setBorder(0); table.addCell(tablein); imageBarc.scaleAbsolute(anchcdba, altocdba); imageBarc.setAbsolutePosition(xposicio, yposicio); documento.add(imageBarc); } catch (Exception e) { } }
private static void imageToPDF(String folder, Collection<Path> all) { for (Path path : all) { Document document = new Document(); String absolutePathInput = path.toFile().getAbsolutePath(); String absolutePathOutput = folder + "/" + path.getFileName() + ".pdf"; if (absolutePathInput.endsWith(".gif") || // absolutePathInput.endsWith(".GIF") || // absolutePathInput.endsWith(".jpg") || // absolutePathInput.endsWith(".JPG") || // absolutePathInput.endsWith(".png") || // absolutePathInput.endsWith(".PNG")) { try { FileOutputStream fos = new FileOutputStream(absolutePathOutput); PdfWriter writer = PdfWriter.getInstance(document, fos); writer.open(); document.open(); int indentation = 0; Image image = Image.getInstance(absolutePathInput); float scaler = ((document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin() - indentation) / image.getWidth()) * 100; image.scalePercent(scaler); document.add(image); document.close(); writer.close(); } catch (Exception e) { e.printStackTrace(); } } } }
public static void buildPdf(PrinterJob job, OutputStream os) throws DocumentException { Document doc = new Document(getPageSizeFromPaper(job.getPaper())); PdfWriter pdfWriter = PdfWriter.getInstance(doc, os); doc.open(); for (int i = 0; job.getNumberOfPages() < 0 || i < job.getNumberOfPages(); i++) { if (job.getNumberOfPages() < 0) { if (!job.render(DUMMYRENDERSPACE, i)) { break; } } PdfContentByte cb = pdfWriter.getDirectContent(); PdfTemplate pdfTemplate = cb.createTemplate(doc.getPageSize().getWidth(), doc.getPageSize().getHeight()); Graphics2D g2d = pdfTemplate.createGraphics( doc.getPageSize().getWidth(), doc.getPageSize().getHeight(), new DefaultFontMapper()); try { if (job.render(g2d, i)) { g2d.dispose(); if (i > 0) { doc.newPage(); } cb.addTemplate(pdfTemplate, 0, 0); } else { throw new PrinterException("Unknow error occured."); } } catch (PrinterException ex) { break; } finally { } } doc.close(); }
/** 当报表没有配置PDF模板时,此方法在显示完每页PDF后执行 现在在此方法中演示显示完每页后向其中添加一个图片 */ public void afterDisplayPdfPageWithoutTemplate(Document document, AbsReportType reportTypeObj) { super.afterDisplayPdfPageWithoutTemplate(document, reportTypeObj); ReportRequest rrequest = reportTypeObj.getReportRequest(); String serverName = rrequest.getRequest().getServerName(); String serverPort = String.valueOf(rrequest.getRequest().getServerPort()); String imgurl = "http://" + serverName + ":" + serverPort + Config.webroot + "wabacusdemo/pdftemplate/logo.gif"; // 构造要添加图片的URL try { Image img = Image.getInstance(imgurl); float width = document.getPageSize().getWidth(); float height = document.getPageSize().getHeight(); // width = width - img.getWidth(); img.setAbsolutePosition(width / 2, height / 2 + 300f); img.setAlignment(Image.ALIGN_CENTER); document.add(img); } catch (Exception e) { e.printStackTrace(); } }
@Override // initialization of the header table public void onEndPage(final PdfWriter writer, final Document document) { final PdfPTable header = new PdfPTable(2); final Phrase p = new Phrase(); final Chunk ck = new Chunk(_challengeTitle + "\n" + _reportTitle, _font); p.add(ck); header.getDefaultCell().setBorderWidth(0); header.addCell(p); header.getDefaultCell().setHorizontalAlignment(com.itextpdf.text.Element.ALIGN_RIGHT); header.addCell( new Phrase(new Chunk("Tournament: " + _tournament + "\nDate: " + _formattedDate, _font))); final PdfPCell blankCell = new PdfPCell(); blankCell.setBorder(0); blankCell.setBorderWidthTop(1.0f); blankCell.setColspan(2); header.addCell(blankCell); final PdfContentByte cb = writer.getDirectContent(); cb.saveState(); header.setTotalWidth(document.right() - document.left()); header.writeSelectedRows(0, -1, document.left(), document.getPageSize().getHeight() - 10, cb); cb.restoreState(); }
private static TableAndHighlighting createTable( PdfWriter docWriter, Document doc, float sideMargins, Dimension scrambleImageSize, String[] scrambles, Puzzle scrambler, HashMap<String, Color> colorScheme, String scrambleNumberPrefix, boolean forceHighlighting) throws DocumentException { PdfContentByte cb = docWriter.getDirectContent(); PdfPTable table = new PdfPTable(3); int charsWide = scrambleNumberPrefix.length() + 1 + (int) Math.log10(scrambles.length); String wideString = ""; for (int i = 0; i < charsWide; i++) { // M has got to be as wide or wider than the widest digit in our font wideString += "M"; } wideString += "."; float col1Width = new Chunk(wideString).getWidthPoint(); // I don't know why we need this, perhaps there's some padding? col1Width += 5; float availableWidth = doc.getPageSize().getWidth() - sideMargins; float scrambleColumnWidth = availableWidth - col1Width - scrambleImageSize.width - 2 * SCRAMBLE_IMAGE_PADDING; int availableScrambleHeight = scrambleImageSize.height - 2 * SCRAMBLE_IMAGE_PADDING; table.setTotalWidth( new float[] { col1Width, scrambleColumnWidth, scrambleImageSize.width + 2 * SCRAMBLE_IMAGE_PADDING }); table.setLockedWidth(true); String longestScramble = ""; String longestPaddedScramble = ""; for (String scramble : scrambles) { if (scramble.length() > longestScramble.length()) { longestScramble = scramble; } String paddedScramble = padTurnsUniformly(scramble, "M"); if (paddedScramble.length() > longestPaddedScramble.length()) { longestPaddedScramble = paddedScramble; } } // I don't know how to configure ColumnText.fitText's word wrapping characters, // so instead, I just replace each character I don't want to wrap with M, which // should be the widest character (we're using a monospaced font, // so that doesn't really matter), and won't get wrapped. char widestCharacter = 'M'; longestPaddedScramble = longestPaddedScramble.replaceAll("\\S", widestCharacter + ""); boolean tryToFitOnOneLine = true; if (longestPaddedScramble.indexOf("\n") >= 0) { // If the scramble contains newlines, then we *only* allow wrapping at the // newlines. longestPaddedScramble = longestPaddedScramble.replaceAll(" ", "M"); tryToFitOnOneLine = false; } boolean oneLine = false; Font scrambleFont = null; try { BaseFont courier = BaseFont.createFont(BaseFont.COURIER, BaseFont.CP1252, BaseFont.EMBEDDED); Rectangle availableArea = new Rectangle( scrambleColumnWidth - 2 * SCRAMBLE_PADDING_HORIZONTAL, availableScrambleHeight - SCRAMBLE_PADDING_VERTICAL_TOP - SCRAMBLE_PADDING_VERTICAL_BOTTOM); float perfectFontSize = fitText( new Font(courier), longestPaddedScramble, availableArea, MAX_SCRAMBLE_FONT_SIZE, true); if (tryToFitOnOneLine) { String longestScrambleOneLine = longestScramble.replaceAll(".", widestCharacter + ""); float perfectFontSizeForOneLine = fitText( new Font(courier), longestScrambleOneLine, availableArea, MAX_SCRAMBLE_FONT_SIZE, false); oneLine = perfectFontSizeForOneLine >= MINIMUM_ONE_LINE_FONT_SIZE; if (oneLine) { perfectFontSize = perfectFontSizeForOneLine; } } scrambleFont = new Font(courier, perfectFontSize, Font.NORMAL); } catch (IOException e) { l.log(Level.INFO, "", e); } catch (DocumentException e) { l.log(Level.INFO, "", e); } boolean highlight = forceHighlighting; for (int i = 0; i < scrambles.length; i++) { String scramble = scrambles[i]; String paddedScramble = oneLine ? scramble : padTurnsUniformly(scramble, NON_BREAKING_SPACE + ""); Chunk ch = new Chunk(scrambleNumberPrefix + (i + 1) + "."); PdfPCell nthscramble = new PdfPCell(new Paragraph(ch)); nthscramble.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); table.addCell(nthscramble); Phrase scramblePhrase = new Phrase(); int nthLine = 1; LinkedList<Chunk> lineChunks = splitScrambleToLineChunks(paddedScramble, scrambleFont, scrambleColumnWidth); if (lineChunks.size() >= MIN_LINES_TO_ALTERNATE_HIGHLIGHTING) { highlight = true; } for (Chunk lineChunk : lineChunks) { if (highlight && (nthLine % 2 == 0)) { lineChunk.setBackground(HIGHLIGHT_COLOR); } scramblePhrase.add(lineChunk); nthLine++; } PdfPCell scrambleCell = new PdfPCell(new Paragraph(scramblePhrase)); // We carefully inserted newlines ourselves to make stuff fit, don't // let itextpdf wrap lines for us. scrambleCell.setNoWrap(true); scrambleCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); // This shifts everything up a little bit, because I don't like how // ALIGN_MIDDLE works. scrambleCell.setPaddingTop(-SCRAMBLE_PADDING_VERTICAL_TOP); scrambleCell.setPaddingBottom(SCRAMBLE_PADDING_VERTICAL_BOTTOM); scrambleCell.setPaddingLeft(SCRAMBLE_PADDING_HORIZONTAL); scrambleCell.setPaddingRight(SCRAMBLE_PADDING_HORIZONTAL); // We space lines a little bit more here - it still fits in the cell height scrambleCell.setLeading(0, 1.1f); table.addCell(scrambleCell); if (scrambleImageSize.width > 0 && scrambleImageSize.height > 0) { PdfTemplate tp = cb.createTemplate( scrambleImageSize.width + 2 * SCRAMBLE_IMAGE_PADDING, scrambleImageSize.height + 2 * SCRAMBLE_IMAGE_PADDING); Graphics2D g2 = new PdfGraphics2D(tp, tp.getWidth(), tp.getHeight(), new DefaultFontMapper()); g2.translate(SCRAMBLE_IMAGE_PADDING, SCRAMBLE_IMAGE_PADDING); try { Svg svg = scrambler.drawScramble(scramble, colorScheme); drawSvgToGraphics2D(svg, g2, scrambleImageSize); } catch (Exception e) { table.addCell("Error drawing scramble: " + e.getMessage()); l.log( Level.WARNING, "Error drawing scramble, if you're having font issues, try installing ttf-dejavu.", e); continue; } finally { g2.dispose(); // iTextPdf blows up if we do not dispose of this } PdfPCell imgCell = new PdfPCell(Image.getInstance(tp), true); imgCell.setBackgroundColor(BaseColor.LIGHT_GRAY); imgCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); imgCell.setHorizontalAlignment(PdfPCell.ALIGN_MIDDLE); table.addCell(imgCell); } else { table.addCell(""); } } TableAndHighlighting tableAndHighlighting = new TableAndHighlighting(); tableAndHighlighting.table = table; tableAndHighlighting.highlighting = highlight; return tableAndHighlighting; }
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(); }