List of usage examples for org.apache.pdfbox.pdmodel.font PDFont getStringWidth
public float getStringWidth(String text) throws IOException
From source file:org.apache.camel.component.pdf.text.PdfUtils.java
License:Apache License
public static float getFontWidth(String str, PDFont font, float fontSize) throws IOException { return font.getStringWidth(str) / PDF_PIXEL_SIZE * fontSize; }
From source file:org.data2semantics.annotate.D2S_SampleAnnotation.java
License:Apache License
/** * This will create a doucument showing various annotations. * /*from ww w . j a v a2s . c om*/ * @param args * The command line arguments. * * @throws Exception * If there is an error parsing the document. */ public static void main(String[] args) throws Exception { PDDocument document = new PDDocument(); try { PDPage page = new PDPage(); document.addPage(page); List annotations = page.getAnnotations(); // Setup some basic reusable objects/constants // Annotations themselves can only be used once! float inch = 72; PDGamma colourRed = new PDGamma(); colourRed.setR(1); PDGamma colourBlue = new PDGamma(); colourBlue.setB(1); PDGamma colourBlack = new PDGamma(); PDBorderStyleDictionary borderThick = new PDBorderStyleDictionary(); borderThick.setWidth(inch / 12); // 12th inch PDBorderStyleDictionary borderThin = new PDBorderStyleDictionary(); borderThin.setWidth(inch / 72); // 1 point PDBorderStyleDictionary borderULine = new PDBorderStyleDictionary(); borderULine.setStyle(PDBorderStyleDictionary.STYLE_UNDERLINE); borderULine.setWidth(inch / 72); // 1 point float pw = page.getMediaBox().getUpperRightX(); float ph = page.getMediaBox().getUpperRightY(); // First add some text, two lines we'll add some annotations to this // later PDFont font = PDType1Font.HELVETICA_BOLD; PDPageContentStream contentStream = new PDPageContentStream(document, page); contentStream.beginText(); contentStream.setFont(font, 18); contentStream.moveTextPositionByAmount(inch, ph - inch - 18); contentStream.drawString("PDFBox"); contentStream.moveTextPositionByAmount(0, -(inch / 2)); contentStream.drawString("Click Here"); contentStream.endText(); contentStream.close(); // Now add the markup annotation, a highlight to PDFBox text PDAnnotationTextMarkup txtMark = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT); txtMark.setColour(colourBlue); txtMark.setConstantOpacity((float) 0.2); // Make the highlight 20% // transparent // Set the rectangle containing the markup float textWidth = (font.getStringWidth("PDFBox") / 1000) * 18; PDRectangle position = new PDRectangle(); position.setLowerLeftX(inch); position.setLowerLeftY(ph - inch - 18); position.setUpperRightX(72 + textWidth); position.setUpperRightY(ph - inch); txtMark.setRectangle(position); // work out the points forming the four corners of the annotations // set out in anti clockwise form (Completely wraps the text) // OK, the below doesn't match that description. // It's what acrobat 7 does and displays properly! float[] quads = new float[8]; quads[0] = position.getLowerLeftX(); // x1 quads[1] = position.getUpperRightY() - 2; // y1 quads[2] = position.getUpperRightX(); // x2 quads[3] = quads[1]; // y2 quads[4] = quads[0]; // x3 quads[5] = position.getLowerLeftY() - 2; // y3 quads[6] = quads[2]; // x4 quads[7] = quads[5]; // y5 txtMark.setQuadPoints(quads); txtMark.setContents("Highlighted since it's important"); annotations.add(txtMark); // Now add the link annotation, so the clickme works PDAnnotationLink txtLink = new PDAnnotationLink(); txtLink.setBorderStyle(borderULine); // Set the rectangle containing the link textWidth = (font.getStringWidth("Click Here") / 1000) * 18; position = new PDRectangle(); position.setLowerLeftX(inch); position.setLowerLeftY(ph - (float) (1.5 * inch) - 20); // down a // couple of // points position.setUpperRightX(72 + textWidth); position.setUpperRightY(ph - (float) (1.5 * inch)); txtLink.setRectangle(position); // add an action PDActionURI action = new PDActionURI(); action.setURI("http://www.pdfbox.org"); txtLink.setAction(action); annotations.add(txtLink); // Now draw a few more annotations PDAnnotationSquareCircle aCircle = new PDAnnotationSquareCircle( PDAnnotationSquareCircle.SUB_TYPE_CIRCLE); aCircle.setContents("Circle Annotation"); aCircle.setInteriorColour(colourRed); // Fill in circle in red aCircle.setColour(colourBlue); // The border itself will be blue aCircle.setBorderStyle(borderThin); // Place the annotation on the page, we'll make this 1" round // 3" down, 1" in on the page position = new PDRectangle(); position.setLowerLeftX(inch); position.setLowerLeftY(ph - (3 * inch) - inch); // 1" height, 3" // down position.setUpperRightX(2 * inch); // 1" in, 1" width position.setUpperRightY(ph - (3 * inch)); // 3" down aCircle.setRectangle(position); // add to the annotations on the page annotations.add(aCircle); // Now a square annotation PDAnnotationSquareCircle aSquare = new PDAnnotationSquareCircle( PDAnnotationSquareCircle.SUB_TYPE_SQUARE); aSquare.setContents("Square Annotation"); aSquare.setColour(colourRed); // Outline in red, not setting a fill aSquare.setBorderStyle(borderThick); // Place the annotation on the page, we'll make this 1" (72points) // square // 3.5" down, 1" in from the right on the page position = new PDRectangle(); // Reuse the variable, but note it's a // new object! position.setLowerLeftX(pw - (2 * inch)); // 1" in from right, 1" // wide position.setLowerLeftY(ph - (float) (3.5 * inch) - inch); // 1" height, 3.5" // down position.setUpperRightX(pw - inch); // 1" in from right position.setUpperRightY(ph - (float) (3.5 * inch)); // 3.5" down aSquare.setRectangle(position); // add to the annotations on the page annotations.add(aSquare); // Now we want to draw a line between the two, one end with an open // arrow PDAnnotationLine aLine = new PDAnnotationLine(); aLine.setEndPointEndingStyle(PDAnnotationLine.LE_OPEN_ARROW); aLine.setContents("Circle->Square"); aLine.setCaption(true); // Make the contents a caption on the line // Set the rectangle containing the line position = new PDRectangle(); // Reuse the variable, but note it's a // new object! position.setLowerLeftX(2 * inch); // 1" in + width of circle position.setLowerLeftY(ph - (float) (3.5 * inch) - inch); // 1" height, 3.5" // down position.setUpperRightX(pw - inch - inch); // 1" in from right, and // width of square position.setUpperRightY(ph - (3 * inch)); // 3" down (top of circle) aLine.setRectangle(position); // Now set the line position itself float[] linepos = new float[4]; linepos[0] = 2 * inch; // x1 = rhs of circle linepos[1] = ph - (float) (3.5 * inch); // y1 halfway down circle linepos[2] = pw - (2 * inch); // x2 = lhs of square linepos[3] = ph - (4 * inch); // y2 halfway down square aLine.setLine(linepos); aLine.setBorderStyle(borderThick); aLine.setColour(colourBlack); // add to the annotations on the page annotations.add(aLine); // Finally all done document.save("testAnnotation.pdf"); } finally { document.close(); } }
From source file:org.dspace.disseminate.CitationDocument.java
License:BSD License
public int drawStringWordWrap(PDPage page, PDPageContentStream contentStream, String text, int startX, int startY, PDFont pdfFont, float fontSize) throws IOException { float leading = 1.5f * fontSize; PDRectangle mediabox = page.findMediaBox(); float margin = 72; float width = mediabox.getWidth() - 2 * margin; List<String> lines = new ArrayList<>(); int lastSpace = -1; while (text.length() > 0) { int spaceIndex = text.indexOf(' ', lastSpace + 1); if (spaceIndex < 0) { lines.add(text);//from w w w .ja v a2 s. c om text = ""; } else { String subString = text.substring(0, spaceIndex); float size = fontSize * pdfFont.getStringWidth(subString) / 1000; if (size > width) { if (lastSpace < 0) // So we have a word longer than the line... draw it anyways lastSpace = spaceIndex; subString = text.substring(0, lastSpace); lines.add(subString); text = text.substring(lastSpace).trim(); lastSpace = -1; } else { lastSpace = spaceIndex; } } } contentStream.beginText(); contentStream.setFont(pdfFont, fontSize); contentStream.moveTextPositionByAmount(startX, startY); int currentY = startY; for (String line : lines) { contentStream.drawString(line); currentY -= leading; contentStream.moveTextPositionByAmount(0, -leading); } contentStream.endText(); return currentY; }
From source file:org.dspace.disseminate.CitationDocumentServiceImpl.java
License:BSD License
@Override public int drawStringWordWrap(PDPage page, PDPageContentStream contentStream, String text, int startX, int startY, PDFont pdfFont, float fontSize) throws IOException { float leading = 1.5f * fontSize; PDRectangle mediabox = page.getMediaBox(); float margin = 72; float width = mediabox.getWidth() - 2 * margin; List<String> lines = new ArrayList<>(); int lastSpace = -1; while (text.length() > 0) { int spaceIndex = text.indexOf(' ', lastSpace + 1); if (spaceIndex < 0) { lines.add(text);/* www . j a v a 2 s. c om*/ text = ""; } else { String subString = text.substring(0, spaceIndex); float size = fontSize * pdfFont.getStringWidth(subString) / 1000; if (size > width) { if (lastSpace < 0) // So we have a word longer than the line... draw it anyways lastSpace = spaceIndex; subString = text.substring(0, lastSpace); lines.add(subString); text = text.substring(lastSpace).trim(); lastSpace = -1; } else { lastSpace = spaceIndex; } } } contentStream.beginText(); contentStream.setFont(pdfFont, fontSize); contentStream.moveTextPositionByAmount(startX, startY); int currentY = startY; for (String line : lines) { contentStream.drawString(line); currentY -= leading; contentStream.moveTextPositionByAmount(0, -leading); } contentStream.endText(); return currentY; }
From source file:org.esteco.jira.pdf.UsingTextMatrix.java
License:Apache License
/** * creates a sample document with some text using a text matrix. * * @param message The message to write in the file. * @param outfile The resulting PDF.// w ww. j a va 2 s . com * @throws IOException If there is an error writing the data. */ public void doIt(String message, String outfile) throws IOException { // the document PDDocument doc = null; try { doc = new PDDocument(); // Page 1 PDFont font = PDType1Font.HELVETICA; PDPage page = new PDPage(PDRectangle.A4); doc.addPage(page); float fontSize = 12.0f; PDRectangle pageSize = page.getMediaBox(); float centeredXPosition = (pageSize.getWidth() - fontSize / 1000f) / 2f; float stringWidth = font.getStringWidth(message); float centeredYPosition = (pageSize.getHeight() - (stringWidth * fontSize) / 1000f) / 3f; PDPageContentStream contentStream = new PDPageContentStream(doc, page, AppendMode.OVERWRITE, false); contentStream.setFont(font, fontSize); contentStream.beginText(); // counterclockwise rotation for (int i = 0; i < 8; i++) { contentStream.setTextMatrix(Matrix.getRotateInstance(i * Math.PI * 0.25, centeredXPosition, pageSize.getHeight() - centeredYPosition)); contentStream.showText(message + " " + i); } // clockwise rotation for (int i = 0; i < 8; i++) { contentStream.setTextMatrix( Matrix.getRotateInstance(-i * Math.PI * 0.25, centeredXPosition, centeredYPosition)); contentStream.showText(message + " " + i); } contentStream.endText(); contentStream.close(); // Page 2 page = new PDPage(PDRectangle.A4); doc.addPage(page); fontSize = 1.0f; contentStream = new PDPageContentStream(doc, page, AppendMode.OVERWRITE, false); contentStream.setFont(font, fontSize); contentStream.beginText(); // text scaling and translation for (int i = 0; i < 10; i++) { contentStream.setTextMatrix(new Matrix(12 + (i * 6), 0, 0, 12 + (i * 6), 100, 100 + i * 50)); contentStream.showText(message + " " + i); } contentStream.endText(); contentStream.close(); // Page 3 page = new PDPage(PDRectangle.A4); doc.addPage(page); fontSize = 1.0f; contentStream = new PDPageContentStream(doc, page, AppendMode.OVERWRITE, false); contentStream.setFont(font, fontSize); contentStream.beginText(); int i = 0; // text scaling combined with rotation contentStream.setTextMatrix(new Matrix(12, 0, 0, 12, centeredXPosition, centeredYPosition * 1.5f)); contentStream.showText(message + " " + i++); contentStream.setTextMatrix(new Matrix(0, 18, -18, 0, centeredXPosition, centeredYPosition * 1.5f)); contentStream.showText(message + " " + i++); contentStream.setTextMatrix(new Matrix(-24, 0, 0, -24, centeredXPosition, centeredYPosition * 1.5f)); contentStream.showText(message + " " + i++); contentStream.setTextMatrix(new Matrix(0, -30, 30, 0, centeredXPosition, centeredYPosition * 1.5f)); contentStream.showText(message + " " + i++); contentStream.endText(); contentStream.close(); doc.save(outfile); } finally { if (doc != null) { doc.close(); } } }
From source file:org.fit.cssbox.render.PDFRenderer.java
License:Open Source License
/** * Writes String to recent PDF page using PDFBox *///from w w w . j a v a 2s. c o m private int writeTextPDFBox(float x, float y, String textToInsert, PDFont font, float fontSize, boolean isUnderlined, boolean isBold, float leading) { // transform X,Y coordinates to Apache PDFBox format y = pageFormat.getHeight() - y - leading * resCoef; try { content.beginText(); content.setFont(font, fontSize); content.newLineAtOffset(x, y); try { content.showText(textToInsert); } catch (IllegalArgumentException e) { // NOTE: seems to happen for embedded icon fonts like glyphicons and fa, add space so there is some text otherwise PDFBox throws IllegalStateException: subset is empty; these work with SVGRenderer content.showText(" "); System.err.println("Error: " + e.getMessage()); } content.endText(); // underlines text if text is set underlined if (isUnderlined) { content.setLineWidth(1); float strokeWidth = font.getStringWidth(textToInsert) / 1000 * fontSize; float lineHeightCalibration = 1f; float yOffset = fontSize / 6.4f; if (isBold) { lineHeightCalibration = 1.5f; yOffset = fontSize / 5.7f; } content.addRect(x, y - yOffset, strokeWidth, resCoef * lineHeightCalibration); content.fill(); } } catch (IOException e) { e.printStackTrace(); return -1; } return 0; }
From source file:org.gfbio.idmg.util.PDFUtil.java
private float getWidth(String s, PDFont pdfFont, float fontSize) throws IOException { return fontSize * pdfFont.getStringWidth(s) / 1000; }
From source file:org.nuxeo.pdf.PDFPageNumbering.java
License:Open Source License
/** * Add page numbers and returns a <i>new</i> Blob. Original blob is not * modified. This code assumes://from ww w.jav a2 s . co m * <ul> * <li>There is no page numbers already (it always draw the numbers)</li> * <li>The pdf is not rotated</li> * <li>Default values apply: * <ul> * <li><code>inStartAtPage</code> and <code>inStartAtNumber</code> are set * to 1 if they are passed < 1.</li> * <li>If <code>inStartAtPage</code> is > number of pages it also is reset * to 1</li> * <li><code>inFontName</code> is set to "Helvetica" if "" or null</li> * <li><code>inFontSize</code> is <= 0, it is set to 16</li> * <li><code>inHex255Color</code> is set to black if "", null or if its * length < 6. Expected format is 0xrrggbb, #rrggbb or just rrggbb</li> * <li><code>inPosition</code> is set to <code>BOTTOM_RIGHT</code> if null</li> * </ul> * </li> * <li></li> * </ul> * * @param inBlob * @param inStartAtPage * @param inStartAtNumber * @param inFontName * @param inFontSize * @param inHex255Color * @param inPosition * @return Blob * @throws IOException * @throws COSVisitorException * * @since 5.9.5 */ public Blob addPageNumbers(int inStartAtPage, int inStartAtNumber, String inFontName, float inFontSize, String inHex255Color, PAGE_NUMBER_POSITION inPosition) throws IOException, COSVisitorException { Blob result = null; PDDocument doc = null; inStartAtPage = inStartAtPage < 1 ? 1 : inStartAtPage; int pageNumber = inStartAtNumber < 1 ? 1 : inStartAtNumber; inFontSize = inFontSize <= 0 ? DEFAULT_FONT_SIZE : inFontSize; int[] rgb = PDFUtils.hex255ToRGB(inHex255Color); try { doc = PDDocument.load(blob.getStream()); List<?> allPages; PDFont font; int max; if (inFontName == null || inFontName.isEmpty()) { font = PDType1Font.HELVETICA; } else { font = PDType1Font.getStandardFont(inFontName); if (font == null) { font = new PDType1Font(inFontName); } } allPages = doc.getDocumentCatalog().getAllPages(); max = allPages.size(); inStartAtPage = inStartAtPage > max ? 1 : inStartAtPage; for (int i = inStartAtPage; i <= max; i++) { String pageNumAsStr = "" + pageNumber; pageNumber += 1; PDPage page = (PDPage) allPages.get(i - 1); PDPageContentStream footercontentStream = new PDPageContentStream(doc, page, true, true); float stringWidth = font.getStringWidth(pageNumAsStr) * inFontSize / 1000f; float stringHeight = font.getFontDescriptor().getFontBoundingBox().getHeight() * inFontSize / 1000; PDRectangle pageRect = page.findMediaBox(); float xMoveAmount, yMoveAmount; if (inPosition == null) { inPosition = PAGE_NUMBER_POSITION.BOTTOM_RIGHT; } switch (inPosition) { case BOTTOM_LEFT: xMoveAmount = 10; yMoveAmount = pageRect.getLowerLeftY() + 10; break; case BOTTOM_CENTER: xMoveAmount = (pageRect.getUpperRightX() / 2) - (stringWidth / 2); yMoveAmount = pageRect.getLowerLeftY() + 10; break; case TOP_LEFT: xMoveAmount = 10; yMoveAmount = pageRect.getHeight() - stringHeight - 10; break; case TOP_CENTER: xMoveAmount = (pageRect.getUpperRightX() / 2) - (stringWidth / 2); yMoveAmount = pageRect.getHeight() - stringHeight - 10; break; case TOP_RIGHT: xMoveAmount = pageRect.getUpperRightX() - 10 - stringWidth; yMoveAmount = pageRect.getHeight() - stringHeight - 10; break; // Bottom-right is the default default: xMoveAmount = pageRect.getUpperRightX() - 10 - stringWidth; yMoveAmount = pageRect.getLowerLeftY() + 10; break; } footercontentStream.beginText(); footercontentStream.setFont(font, inFontSize); footercontentStream.moveTextPositionByAmount(xMoveAmount, yMoveAmount); footercontentStream.setNonStrokingColor(rgb[0], rgb[1], rgb[2]); footercontentStream.drawString(pageNumAsStr); footercontentStream.endText(); footercontentStream.close(); } File tempFile = File.createTempFile("pdfutils-", ".pdf"); doc.save(tempFile); result = new FileBlob(tempFile); Framework.trackFile(tempFile, result); } finally { if (doc != null) { doc.close(); } } return result; }
From source file:org.nuxeo.pdf.PDFWatermarking.java
License:Open Source License
/** * Adds the watermark to the Blob passed to the constructor. * <p>/*w ww . j a v a 2s .co m*/ * If no setter has been used, the DEFAULT_nnn values apply * <p> * If * <code>text</text> is empty or null, a simple copy of the original Blob is returned * <p> * With thanks to the sample code found at https://issues.apache.org/jira/browse/PDFBOX-1176 * and to Jack (https://jackson-brain.com/a-better-simple-pdf-stamper-in-java/) * * @return a new Blob with the watermark on each page * * @throws ClientException * * @since 6.0 */ public Blob watermark() throws ClientException { Blob result = null; PDDocument pdfDoc = null; PDPageContentStream contentStream = null; if (text == null || text.isEmpty()) { try { File tempFile = File.createTempFile("nuxeo-pdfwatermarking-", ".pdf"); blob.transferTo(tempFile); result = new FileBlob(tempFile); // Just duplicate the info result.setFilename(blob.getFilename()); result.setMimeType(blob.getMimeType()); result.setEncoding(blob.getEncoding()); Framework.trackFile(tempFile, result); return result; } catch (IOException e) { throw new ClientException(e); } } // Set up the graphic state to handle transparency // Define a new extended graphic state PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState(); // Set the transparency/opacity extendedGraphicsState.setNonStrokingAlphaConstant(alphaColor); try { pdfDoc = PDDocument.load(blob.getStream()); PDFont font = PDType1Font.getStandardFont(fontFamily); int[] rgb = PDFUtils.hex255ToRGB(hex255Color); List<?> allPages = pdfDoc.getDocumentCatalog().getAllPages(); int max = allPages.size(); for (int i = 0; i < max; i++) { contentStream = null; PDPage page = (PDPage) allPages.get(i); PDRectangle pageSize = page.findMediaBox(); PDResources resources = page.findResources(); // Get the defined graphic states. HashMap<String, PDExtendedGraphicsState> graphicsStateDictionary = (HashMap<String, PDExtendedGraphicsState>) resources .getGraphicsStates(); if (graphicsStateDictionary != null) { graphicsStateDictionary.put("TransparentState", extendedGraphicsState); resources.setGraphicsStates(graphicsStateDictionary); } else { Map<String, PDExtendedGraphicsState> m = new HashMap<>(); m.put("TransparentState", extendedGraphicsState); resources.setGraphicsStates(m); } if (invertY) { yPosition = pageSize.getHeight() - yPosition; } float stringWidth = font.getStringWidth(text) * fontSize / 1000f; int pageRot = page.findRotation(); boolean pageRotated = pageRot == 90 || pageRot == 270; boolean textRotated = textRotation != 0 && textRotation != 360; int totalRot = pageRot - textRotation; float pageWidth = pageRotated ? pageSize.getHeight() : pageSize.getWidth(); float pageHeight = pageRotated ? pageSize.getWidth() : pageSize.getHeight(); double centeredXPosition = pageRotated ? pageHeight / 2f : (pageWidth - stringWidth) / 2f; double centeredYPosition = pageRotated ? (pageWidth - stringWidth) / 2f : pageHeight / 2f; contentStream = new PDPageContentStream(pdfDoc, page, true, true, true); contentStream.beginText(); contentStream.setFont(font, fontSize); contentStream.appendRawCommands("/TransparentState gs\n"); contentStream.setNonStrokingColor(rgb[0], rgb[1], rgb[2]); if (pageRotated) { contentStream.setTextRotation(Math.toRadians(totalRot), centeredXPosition, centeredYPosition); } else if (textRotated) { contentStream.setTextRotation(Math.toRadians(textRotation), xPosition, yPosition); } else { contentStream.setTextTranslation(xPosition, yPosition); } contentStream.drawString(text); contentStream.endText(); contentStream.close(); contentStream = null; } result = PDFUtils.saveInTempFile(pdfDoc); } catch (IOException | COSVisitorException e) { throw new ClientException(e); } finally { if (contentStream != null) { try { contentStream.close(); } catch (IOException e) { // Ignore } } PDFUtils.closeSilently(pdfDoc); } return result; }
From source file:org.nuxeo.pdf.service.PDFTransformationServiceImpl.java
License:Apache License
@Override public Blob applyTextWatermark(Blob input, String text, WatermarkProperties properties) { // Set up the graphic state to handle transparency // Define a new extended graphic state PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState(); // Set the transparency/opacity extendedGraphicsState.setNonStrokingAlphaConstant((float) properties.getAlphaColor()); try (PDDocument pdfDoc = PDDocument.load(input.getStream())) { PDFont font = PDType1Font.getStandardFont(properties.getFontFamily()); float watermarkWidth = (float) (font.getStringWidth(text) * properties.getFontSize() / 1000f); int[] rgb = PDFUtils.hex255ToRGB(properties.getHex255Color()); for (Object o : pdfDoc.getDocumentCatalog().getAllPages()) { PDPage page = (PDPage) o;/* w ww. jav a 2 s . c om*/ PDRectangle pageSize = page.findMediaBox(); PDResources resources = page.findResources(); // Get the defined graphic states. HashMap<String, PDExtendedGraphicsState> graphicsStateDictionary = (HashMap<String, PDExtendedGraphicsState>) resources .getGraphicsStates(); if (graphicsStateDictionary != null) { graphicsStateDictionary.put("TransparentState", extendedGraphicsState); resources.setGraphicsStates(graphicsStateDictionary); } else { Map<String, PDExtendedGraphicsState> m = new HashMap<>(); m.put("TransparentState", extendedGraphicsState); resources.setGraphicsStates(m); } try (PDPageContentStream contentStream = new PDPageContentStream(pdfDoc, page, true, true, true)) { contentStream.beginText(); contentStream.setFont(font, (float) properties.getFontSize()); contentStream.appendRawCommands("/TransparentState gs\n"); contentStream.setNonStrokingColor(rgb[0], rgb[1], rgb[2]); Point2D position = computeTranslationVector(pageSize.getWidth(), watermarkWidth, pageSize.getHeight(), properties.getFontSize(), properties); contentStream.setTextRotation(Math.toRadians(properties.getTextRotation()), position.getX(), position.getY()); contentStream.drawString(text); contentStream.endText(); } } return saveInTempFile(pdfDoc); } catch (Exception e) { throw new NuxeoException(e); } }