iText embedded ttf font not visible in Adobe Reader - pdf

I'm stamping an existing PDF file with extra information using the iText library.
The extra information is text that should be rendered in a custom TTF font.
Problem is that the text is not visible in the Adobe Reader only.
Other PDF viewers, such as the default eVince reader in Ubuntu and the Google online PDF reader render the stamped text in the custom embedded font just fine.
I tried multiple encodings, such as Cp1251, BaseFont.Identity_H, ...
The code where the magic happens:
PdfReader pdfReader = new PdfReader(new FileInputStream(inputPdf));
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream("stamped.pdf"));
PdfContentByte canvas = pdfStamper.getOverContent(1);
String text = "The stamp";
BaseFont bf = BaseFont.createFont("assign.ttf", "Cp1251",BaseFont.EMBEDDED);
canvas.beginText();
canvas.setColorFill(BaseColor.BLUE);
canvas.setFontAndSize(bf, 13);
canvas.moveText(310, 600);
canvas.showText(text);
pdfStamper.close();

You have a syntax problem. Text state in PDF is marked with BT and ET. These operators are added using the beginText() and endText() methods. You have a BT, but no ET. Adobe Reader is more strict than the other viewers (that's why I prefer Adobe Reader over all other viewers: people should respect the syntax when writing code).
Add the following line before pdfStamper.close();
canvas.endText();
Better yet, read my book and you'll find out you can reduce the complexity of your code by using ColumnText.showTextAligned().

Related

Why is flying saucer always printing PDF on A4 paper?

I'm trying to save an html document to PDF using flyingsaucer but the generated document always ends up having an A4 dimension when I look at the Document Properties from Adobe Reader (Page Size: 8.26 x 11.69 in).
I did read the documentation and I'm passing the css #page {size: letter;} style. And while it does have an effect on the output, the page size always remains 8.26 x 11.69 in Adobe Reader. For example, if I set the page size to legal, my PDF is still the size of a A4 but the top of the document is missing as if it had fell off the "paper".
I'm not sure if the problem falls on the itext side or the flying saucer side. I was using a fairly old version so my first step was to upgrade to the latest 9.1.6 version of flying saucer. I also moved from itext 2.0.8 to openPDF 1.0.1 but I'm still getting the same behavior.
I also traced in the debugger up to the com.lowagie.text.Document creation in ITextRenderer and at this point the document size passed is correct. That makes me think that the issue might be in openPDF / iText but I can't find what I'm doing wrong.
It turns out the PDF generation was correctly using the #page size declaration and the problem was occurring later in our software. What I had not noticed is that after the generation of the PDF another method was called to merge multiple PDFs into one. This method should probably not have been called, but that's another story.
The bottom line is this method created a new com.lowagie.text.Document(), which by default creates an A4 sized document, and then was iterating over all pages of the pdf, adding the pages to the new document using pdfWriter.getImportedPage(pdfReader, currentPage++). These imported pages did not retain their original size.
I fixed it by passing the page size of the fist page when creating the merged document object:
document = new Document(pdfReader.getPageSize(1));
The real problem is that you're (unwittingly) using software that is no longer supported. Anything that still has the namespace lowagie (the founder and CTO of iText) is really outdated.
If you simply want to convert HTML to pdf, why not use iText directly and cut out the middle-man?
We have multiple options for you.
XMLWorker (iText5 based code that converts HTML to pdf)
pdfHTML (iText7 based add-on that converts HTML5/CSS3 to pdf)
This is a rather extensive code-sample for using pdfHTML:
public void createPdf(String src, String dest, String resources) throws IOException {
try {
FileOutputStream outputStream = new FileOutputStream(dest);
WriterProperties writerProperties = new WriterProperties();
//Add metadata
writerProperties.addXmpMetadata();
PdfWriter pdfWriter = new PdfWriter(outputStream, writerProperties);
PdfDocument pdfDoc = new PdfDocument(pdfWriter);
pdfDoc.getCatalog().setLang(new PdfString("en-US"));
//Set the document to be tagged
pdfDoc.setTagged();
pdfDoc.getCatalog().setViewerPreferences(new PdfViewerPreferences().setDisplayDocTitle(true));
//Set meta tags
PdfDocumentInfo pdfMetaData = pdfDoc.getDocumentInfo();
pdfMetaData.setAuthor("Joris Schellekens");
pdfMetaData.addCreationDate();
pdfMetaData.getProducer();
pdfMetaData.setCreator("iText Software");
pdfMetaData.setKeywords("example, accessibility");
pdfMetaData.setSubject("PDF accessibility");
//Title is derived from html
// pdf conversion
ConverterProperties props = new ConverterProperties();
FontProvider fp = new FontProvider();
fp.addStandardPdfFonts();
fp.addDirectory(resources);//The noto-nashk font file (.ttf extension) is placed in the resources
props.setFontProvider(fp);
props.setBaseUri(resources);
//Setup custom tagworker factory for better tagging of headers
DefaultTagWorkerFactory tagWorkerFactory = new AccessibilityTagWorkerFactory();
props.setTagWorkerFactory(tagWorkerFactory);
HtmlConverter.convertToPdf(new FileInputStream(src), pdfDoc, props);
pdfDoc.close();
} catch (Exception e) {
e.printStackTrace();
}
}
You can find more information at http://itextpdf.com/itext7/pdfHTML

Reader extensions not needed anymore for digital signature in Acrobat Reader DC?

In a business environment we have Adobe LiveCycle ES for several years.
A key feature is to enable "Reader extensions" in PDFs, which unlocks some features in Adobe Reader for reader extended PDFs. One of them was allowing user to digitally sign empty signature fields in Adobe Reader.
I remember nothing happened when clicking on the signature field in Adobe Reader if the PDF was not "reader extended". This is the case e.g. if the PDF was generated using iText. This limitation is still confirmed in iText FAQ which is supposed to be up-to-date as the project is active.
I recently reexecuted some old code and surprisingly the empty signature field could be signed in Acrobat Reader DC.
The code generating the PDF is the following :
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(filename));
document.open();
document.add(new Paragraph("Hello World!"));
document.close();
The code for adding the signature field :
PdfReader pdf = new PdfReader(inputstream);
PdfStamper stp = new PdfStamper(pdf, new FileOutputStream(filename));
PdfFormField sig = PdfFormField.createSignature(stp.getWriter());
sig.setWidget(new Rectangle(100, 100, 200, 200), null);
sig.setFlags(PdfAnnotation.FLAGS_PRINT);
sig.put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g"));
sig.setFieldName("Signature1");
sig.setPage(1);
stp.addAnnotation(sig, 1);
stp.close();
What changed ? I guess Adobe Acrobat DC has removed some reader extensions requirements, but I could not find any release note explaining this.

Adobe Reader can't display unicode font of pdf added with iText

I'd like to stamp text to a certain pdf with iText. As this text can be cyrillic I use a unicode font and encoding.
The following sample code represents how I do it:
string inputFile = #"sampleStamped.pdf";
PdfReader reader;
PdfStamper stamper;
FileStream fs;
byte[] binaryPdf = File.ReadAllBytes(inputFile);
reader = new PdfReader(binaryPdf);
fs = new FileStream(inputFile, FileMode.Create, FileAccess.Write);
stamper = new PdfStamper(reader, fs);
BaseFont bf = BaseFont.CreateFont("c:/windows/fonts/arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
PdfContentByte cb = stamper.GetOverContent(1);
Phrase p = new Phrase();
p.Font = new Font(bf, 25, Font.NORMAL, BaseColor.BLUE);
p.Add("Sample Text");
ColumnText.ShowTextAligned(cb, PdfContentByte.ALIGN_LEFT, p, 200, 200, 0);
if (stamper != null)
stamper.Close();
if (fs != null)
fs.Close();
if (reader != null)
reader.Close();
The program works as expected and without errors. But if I want to open the stamped pdf in Acrobat Reader 11 or DC on Windows it says that there are proplems to display content and the stamped text is not there.
I use itextsharp 5.5.8.
Any idea how to fix this problem?
Thanks
This is not an issue of iText(Sharp) but a quirk (a feature?) of Adobe Reader.
Your sample file claims to be a PDF 1.2 file. Adobe Reader seems to behave differently when confronted with composite fonts in PDF 1.2 files.
You can check this by patching your sampleStamped.pdf, simply replace the first bytes %PDF-1.2 by %PDF-1.3 and open the file in Adobe Reader... no problem anymore.
Thus, you should make sure that your stamped PDF claims to be at least PDF 1.3. If you stamp your PDF 1.2 file, you can do so by creating the PdfStamper like this:
stamper = new PdfStamper(reader, fs, (char)3);
The result:

Dynamically Fill your PDF Forms using silverlight

string pdfTemplate = #"Trust App form.pdf";
string newFile = #"Trust App form Completed.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(
newFile, FileMode.Create));
AcroFields pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("trust.trustee.entityname.line1", "Gulistan-e-Jauhar Karachi");
pdfStamper.FormFlattening = false;
pdfStamper.Close();
I am able to fill pdf forms using Itext sharp pdf.
But problem is this pdf is for .net. I WANT TO USE IT IN SILVERLIGHT.
Is there any alternative? for filling pdf form in silverlight... what i think itext sharp give silverpdf (http://silverpdf.codeplex.com/) but there is pdfstamper and acrofields classes in silverpdf.
SilverPDF looks to be inspired/based-on iTextSharp and PDFSharp, but it doesn't use an identical class layout by any means.
I just poked around in their code a bit (they have no docs that I could find), and it looks like you need to get the field's PdfAcroField object from the PdfAcroForm, which you get from a PdfDocument, which in turn you get from PdfReader.open(...).
When the docs aren't good enough, check the code if at all possible.

Programmatically enable Adobe PDF usage rights

Is there any way to programmatically enable Adobe PDF usage rights from .net code ?
I'm using ITextSharp library to fill an XFA Form with XML Data (generated from app),
but the output PDF does not have usage rights enabled, thus the users cannot interact with it (that wouldn't normally be a problem, BUT the original PDF is gov supplied, and
the user must click some validation buttons, and that process is user/company specific)
This could be manually accomplished from Adobe Reader but you have to have an adobe acrobat professional licence..
Google is saying that "Only Adobe products can do that" ..
(http://old.nabble.com/Enable-Adobe-Reader-usage-rights-td14276927.html)
string pathPDF = #"C:\original.pdf";
string pathCreated = #"C:\created.pdf";
string pathXml = #"C:\data.xml";
using (PdfStamper stamper = new PdfStamper(new PdfReader(pathPDF), System.IO.File.OpenWrite(pathCreated)))
{
stamper.FormFlattening = false;
stamper.AcroFields.Xfa.FillXfaForm(pathXml);
stamper.Close();
}
The only way to do it programitically is to use Adobe Reader Extension Server. You can review Adobe whitepaper here: http://www.adobe.com/sea/products/server/readerextensions/pdfs/readerextensionsserver_ds.pdf
In the case above you would use iTextSharp to create Pdf document and then use Adobe Reader Extension Server to allow Pdf document to have extended functionality in Adobe Reader.
However, there is a small window that allows you to work with iTextSharp and fill-in already Reader-enabled PDF documents. If you have such Pdf document (Reader Enabled), then you can use iText/iTextSharp to fill in XFA data. You can check example here:
http://itextpdf.com/examples/iia.php?id=166
Good luck!
Currently only 2 products can enable usage rights:
Adobe Acrobat - for less that 500 users
Adobe LiveCycle Reader Extensions - more than 500 users
There have been some findings regarding this feature here.
No. Adobe uses Strong Crypto to ensure it... PPK I believe.
Google is saying that "Only Adobe products can do that"
That's because only Adobe products can do that. You can pay for some Acrobat server product or other... $$$... but that's it.
This worked for me:
string TempFilename = Path.GetTempFileName();
PdfReader pdfReader = new PdfReader(FileName);
//PdfStamper stamper = new PdfStamper(pdfReader, new FileStream(TempFilename, FileMode.Create));
PdfStamper stamper = new PdfStamper(pdfReader, new FileStream(TempFilename, FileMode.Create), '\0', true);
AcroFields fields = stamper.AcroFields;
AcroFields pdfFormFields = pdfReader.AcroFields;
foreach (KeyValuePair<string, AcroFields.Item> kvp in fields.Fields)
{
string FieldValue = GetXMLNode(XMLFile, kvp.Key);
if (FieldValue != "")
{
fields.SetField(kvp.Key, FieldValue);
}
}
stamper.FormFlattening = false;
stamper.Close();
pdfReader.Close()
you can complete it using PdfStamper
when using PdfStamper use thi code
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(
newPath, FileMode.CreateNew, FileAccess.Write), '\0', true);
if the form is Reader Extension enabled it will work