PDFBox True Type font bold - pdfbox

I'm developing an application that must create a PDF file with different font styles (sometimes bold, sometimes italic and sometimes regular). The Font that I must use is Eras Medium BT (True Type), and I load it using a local file named "erasm.TTF". My question is, how can I draw text in bold or italics using my Eras font file?
I've got a legacy code that uses iText to generate a similar PDF, and to get a bold Font I just need to call this function:
public Font getFontErasMDBTBold9(){
FontFactory.register(fontPath + "erasm.TTF", "ERASM");
fontErasMDBT9 = FontFactory.getFont("ERASM", 9, Font.BOLD, Color.BLACK);
return fontErasMDBT9;
}
Edit:
I've seen in other questions that it can be done using different font variants, or artificially by using raw commands. What I want is to use the original font and set some text to be bold, other text italics and the rest just regular.
Is it possible to open a Font in bold style or italic style like in iText?

Thanks for your comments and advices. Finally I used the setRenderingMode method of the PDFPageContentStream class to set the different styles of my text. Here's a private method to write some text with the desired render mode:
private void writeText(PDPageContentStream contentStream, String text, PDFont font,
int size, float xPos, float yPos, RenderingMode renderMode = RenderingMode.FILL) {
contentStream.beginText()
contentStream.setFont(font, size)
contentStream.newLineAtOffset(xPos, yPos)
contentStream.setRenderingMode(renderMode)
contentStream.showText(text)
contentStream.endText()
}
And here is the code to write regular text and bold text.
private void addFrontPage(PDDocument document) {
PDPage frontPage = newPage()
PDPageContentStream contentStream = new PDPageContentStream(document, frontPage)
// Write text
String text = "This is a bold text"
writeText(contentStream, text, eras, 18, 25, 500, RenderingMode.FILL_STROKE)
text = "and this is a regular text"
writeText(contentStream, text, eras, 9, 25, 480)
contentStream.close()
document.addPage(frontPage)
}
Note: The code is writen in Groovy language.

Here is a full example to explain how to render the used font to appear in Italic & bold:
String message = "This is a message in the page.";
PDDocument document = new PDDocument();
PDPage page = new PDPage();
PDPageContentStream contentStream = new PDPageContentStream( document, page, AppendMode.APPEND, true, true);
contentStream.beginText();
contentStream.setFont( font, fontSize ); // set font and font size.
contentStream.setNonStrokingColor( 1f, 0, 0 ); // set text color to red
// Modify font to appear in Italic:
Matrix matrix = new Matrix( 1, 0, .2f, 1, 7, 5 );
contentStream.setTextMatrix( matrix );
// Modify the font to appear in bold:
contentStream.setRenderingMode( RenderingMode.FILL_STROKE );
contentStream.setStrokingColor( 1f, 0, 0 );
// Write text:
contentStream.showText( message );
contentStream.endText();
contentStream.close();
document.addPage( page );
document.save( PDF_FILE_PATH );
document.close();

Related

How to pass font name as string in pdf file with Java iText

I am generating pdf report with few inputs like font name, font size. I tried to create a font using below code.
Font font = new Font(FontFamily.TIMES_ROMAN,50.0f,Font.UNDERLINE,BaseColor.RED);
Here, how pass font name that is TIMES_ROMAN as a string?
Here's a quick way on how you can achieve the desired behavior with iText 7:
final PdfDocument pdfDocument = new PdfDocument(new PdfWriter(DEST));
PdfFont font = PdfFontFactory.createFont(FontProgramFactory.createFont(StandardFonts.TIMES_ROMAN));
Style myStyle = new Style()
.setFontSize(50)
.setUnderline()
.setFontColor(RED)
.setFont(font);
try (final Document document = new Document(pdfDocument)) {
document.add(new Paragraph("Hello World!").addStyle(myStyle));
document.add(new Paragraph("Hello World!").setFont(font)
.setFontSize(50)
.setUnderline()
.setFontColor(RED));
}
You can also define the font on a Document level (I'm showing Style and directly on the Paragraph).

iTextsharp font color different in PDF

I'm creating a PDF with images and text. Text can be of varying color. I convert the color from the HTML color code to get me a System.Drawing.Color object but the color turns out differently in the generated PDF. In one particular instance, the html code is 3C3C3C and it comes out as 3C403E. I check the color by using a color picker to get the color in the PDF.
var color = System.Drawing.ColorTranslator.FromHtml("#3C3C3C);
iTextSharp.text.Font font = font = FontFactory.GetFont(FontFactory.HELVETICA);
font.Color = new BaseColor(color);
// boxValue is a string
Phrase phrase = new Phrase(boxValue, font);
ColumnText columnText = new ColumnText(canvas);
columnText.SetSimpleColumn(boxRectangle);
columnText.Leading = lineHeight;
columnText.SetLeading(lineHeight, 0);
columnText.SetText(phrase);
columnText.Alignment = alignment;
columnText.Go();
It turns out that it does save the actual color in the PDF. I discovered this by using a PDF inspector and do see the correct values used.
public static BaseColor stringToBaseColor(string code)
{
Color color = ColorFromString(code);
BaseColor b = new BaseColor(color);
return ColorToBaseColor(color);
}
public static BaseColor ColorToBaseColor(Color color)
{
return new BaseColor(color);
}
public static Color ColorFromString(string code)
{
string[] colors = code.Split(',');
List<int> myInts = Array.ConvertAll(colors, s => int.Parse(s)).ToList();
return Color.FromArgb(myInts[0], myInts[1], myInts[2]);
}

PDFBOX, Reading a pdf line by line and extracting text properties

I am using pdfbox to extract text from pdf files. I read the pdf document as follows
PDFParser parser = null;
String text = "";
PDFTextStripper stripper = null;
PDDocument pdoc = null;
COSDocument cdoc = null;
File file = new File("path");
try {
parser = new PDFParser(new FileInputStream(file));
} catch (IOException e) {
e.printStackTrace();
}
try {
parser.parse();
cdoc = parser.getDocument();
stripper = new PDFTextStripper();
pdoc = new PDDocument(cdoc);
stripper.setStartPage(1);
stripper.setEndPage(2);
text = stripper.getText(pdoc);
System.out.println(text);
} catch (IOException e) {
e.printStackTrace();
}
But what I want to do is read the document line by line and to extract the text properties such as bold,italic, from each line.
How can I achieve this with pdfbox library
extract the text properties such as bold,italic, from each line. How can I achieve this with pdfbox library
Properties such as bold and italic are not first-class properties in a PDF.
Bold or italic writing in PDFs is achieved either using
different fonts (which is the better way); in this case one can try to determine whether or not the fonts are bold or italic by
looking at the font name: it may contain a substring "bold", "italic", "oblique"...
looking at some optional properties of the font, e.g. font weight...
inspecting embedded font file.
Neither of these methods is fool-proof; or
using the same font as for non-bold, non-italic text but using special techniques to make them appear bold or italic (aka poor man's bold), e.g.
not only filling the glyph contours but also drawing a thicker line along it for a bold impression,
drawing the glyph twice, the second time slightly displaced, also for a bold impression,
using a text or transformation matrix to slant the letters for an italic impression.
By overriding the PDFTextStripper methods with such tests accordingly, you may achieve a fairly good guess rate for styles during PDF text extraction.

write lines on PDF

I want to write line by line on a pdf document
the code I have is writing the text in the center of the page
how can I write line by line?
// Create a new PDF document
PdfDocument document = new PdfDocument();
document.Info.Title = "Created with PDFsharp";
// Create an empty page
PdfPage page = document.AddPage();
// Get an XGraphics object for drawing
XGraphics gfx = XGraphics.FromPdfPage(page);
// Create a font
XFont font = new XFont("Verdana", 20, XFontStyle.BoldItalic);
// Draw the text
gfx.DrawString("Hello, World!", font, XBrushes.Black,
new XRect(0, 0, page.Width, page.Height),
XStringFormats.TopCenter);
With new XRect(0, 0, page.Width, page.Height) you specify where text will be drawn.
Use a smaller rectangle and increase the second value from line to line.
PDFsharp includes several examples:
http://pdfsharp.net/wiki/PDFsharpSamples.ashx
Especially check Text Layout. Sample code included with the source package of PDFsharp.
Also check out MigraDoc as it adds pagebreaks automatically.
http://pdfsharp.net/wiki/MigraDocSamples.ashx

How to exactly position an Image inside an existing PDF page using PDFBox?

I am able to insert an Image inside an existing pdf document, but the problem is,
The image is placed at the bottom of the page
The page becomes white with the newly added text showing on it.
I am using following code.
List<PDPage> pages = pdDoc.getDocumentCatalog().getAllPages();
if(pages.size() > 0){
PDJpeg img = new PDJpeg(pdDoc, in);
PDPageContentStream stream = new PDPageContentStream(pdDoc,pages.get(0));
stream.drawImage(img, 60, 60);
stream.close();
}
I want the image on the first page.
PDFBox is a low-level library to work with PDF files. You are responsible for more high-level features. So in this example, you are placing your image at (60, 60) starting from lower-left corner of your document. That is what stream.drawImage(img, 60, 60); does.
If you want to move your image somewhere else, you have to calculate and provide the wanted location (perhaps from dimensions obtained with page.findCropBox(), or manually input your location).
As for the text, PDF document elements are absolutely positioned. There are no low-level capabilities for re-flowing text, floating or something similar. If you write your text on top of your image, it will be written on top of your image.
Finally, for your page becoming white -- you are creating a new content stream and so overwriting the original one for your page. You should be appending to the already available stream.
The relevant line is:
PDPageContentStream stream = new PDPageContentStream( pdDoc, pages.get(0));
What you should do is call it like this:
PDPageContentStream stream = new PDPageContentStream( pdDoc, pages.get(0), true, true);
The first true is whether to append content, and the final true (not critical here) is whether to compress the stream.
Take a look at AddImageToPDF sample available from PDFBox sources.
Try this
doc = PDDocument.load( inputFileName );
PDXObjectImage ximage = null;
ximage = new PDJpeg(doc, new FileInputStream( image )
PDPage page = (PDPage)doc.getDocumentCatalog().getAllPages().get(0);
PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true);
contentStream.drawImage( ximage, 425, 675 );
contentStream.close();
This prints the image in first page. If u want to print in all pages just put on a for loop with a condition of number of pages as the limit.
This worked for me well!
So late answer but this is for who works on it in 2020 with Kotlin: drawImage() is getting float values inside itself so try this:
val file = File(getPdfFile(FILE_NAME))
val document = PDDocument.load(file)
val page = document.getPage(0)
val contentStream: PDPageContentStream
contentStream = PDPageContentStream(document, page, true, true)
// Define a content stream for adding to the PDF
val bitmap: Bitmap? = ImageSaver(this).setFileName("sign.png").setDirectoryName("signature").load()
val mediaBox: PDRectangle = page.mediaBox
val ximage: PDImageXObject = JPEGFactory.createFromImage(document, bitmap)
contentStream.drawImage(ximage, mediaBox.width - 4 * 65, 26f)
// Make sure that the content stream is closed:
contentStream.close()
// Save the final pdf document to a file
pdfSaveLocation = "$directoryPDF/$UPDATED_FILE_NAME"
val pathSave = pdfSaveLocation
document.save(pathSave)
document.close()
I am creating a new PDF and running below code in a loop - to add one image per page and below co-ordinates and height and width values work well for me.
where out is BufferedImage reference variable
PDPage page = new PDPage();
outputdocument.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(outputdocument, page, AppendMode.APPEND, true);
PDImageXObject pdImageXObject = JPEGFactory.createFromImage(outputdocument, out);
contentStream.drawImage(pdImageXObject, 5, 2, 600, 750);
contentStream.close();
This link gives you details about Class PrintImageLocations.
This PrintImageLocations will give you the x and y coordinates of the images.
Usage: java org.apache.pdfbox.examples.util.PrintImageLocations input-pdf