IText 5.5.11 and thymeleaf : Arabic characters - pdf

I am wiriting HTML to PDF Conversion of Arabic Text from Itext 5.5.11 and ITextRenderer but the The letters are reversed
I tried to follow the answer of this question,
Arabic characters from html content to pdf using iText
but the problem is always posed
My fonction is like :
public void createPdf(String templateName, Map map) throws Exception {
Assert.notNull(templateName, "The templateName can not be null");
Context ctx = new Context();
if (map != null) {
Iterator itMap = map.entrySet().iterator();
while (itMap.hasNext()) {
Map.Entry pair = (Map.Entry) itMap.next();
ctx.setVariable(pair.getKey().toString(), pair.getValue());
}
}
String processedHtml = templateEngine.process(templateName, ctx);
FileOutputStream os = null;
//String fileName = UUID.randomUUID().toString();
try {
// final File outputFile = File.createTempFile(fileName, ".pdf");
os = new FileOutputStream(new File(directoryPathConfig.getPathDefaultDirectory("pdfOutput.path")).getAbsolutePath() + "/World.pdf");
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(processedHtml,new ClassPathResource("/static/").getURL().toExternalForm());
renderer.getFontResolver().addFont("fonts/NotoNaskhArabic-Regular.ttf", "Noto Naskh Arabic", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, null);
renderer.layout();
renderer.createPDF(os, false);
renderer.finishPDF();
System.out.println("PDF created successfully");
}
finally {
if (os != null) {
try {
os.close();
} catch (IOException e) { /*ignore*/ }
}
}
}
In my themplate I did it like this :
<p dir="rtl" style="font-family: Noto Naskh Arabic;text-align: center;text-decoration: underline; font-size: 18px;">الشباك الوحيد للجماعة</p>

Related

How to identify whether the text is boxed in PDF using PDFBOX?

I am trying to check whether the text is BOXED using apache PDFBOX. for few PDF the below code wont work.
public class PDFBoxReader extends PDFGraphicsStreamEngine {
private static ArrayList<Rectangle2D> recList = new ArrayList<Rectangle2D>();
public PDFBoxReader(PDPage page) {
super(page);
}
public static boolean isTextBoxed(PDDocument document, String text) {
StingBuffer boxedText = new StringBuffer();
for (PDPage page : document.getPages()) {
PDFBoxReader reader = new PDFBoxReader(page);
try {
PDFTextStripperByArea stripper = new PDFTextStripperByArea();
rectList = new ArrayList<Rectangle2D>();
reader.processPage(page);
for (Rectangle2D react : rectList) {
Double y = page.cropBox().getUpperRightY() - rect.getY() - rect.getHeight();
rect.setRect(rect.getX(), y, rect.getWidth(), rect.getWidth(), rect.getHeight());
stripper.addRegion("box", rect);
stripper.extractRegions(page);
boxedText.append(stripper.getTextForRegion("box"));
}
if (isTextMatched(text, stripper.getTextForRegion("box"))) {
return true;
}
} catch (IoException exception) {
// exception is handled here
}
}
}
// some more methods here
}
PDF dont have any acroform. it has a paragraph in a bordered box at the end of the page.

Converting Docx to PDF getting spacing issues

I am trying to convert a document to PDF using apache POI or Docx4j ( Apache FOP) both are giving issues while conversion.
While using apache POI it leaves line spaces when it is not there in document also.
But while using Apache FOP the table heading and table is getting shifted on next page.
I am new to this.
Can you advise which one would be better and how to avoid these spaces.
Here are code samples
SampleCode1 using apache POI
try
{
oLog.error("function POI begin");
String WordDocFile= "C:\\PRPCPersonalEdition\\tomcat\\TestDocument.docx";
oLog.error("WordDocFile is"+WordDocFile);
String pdfDocFile="C:\\PRPCPersonalEdition\\tomcat\\TestDocument.pdf";
oLog.error("pdfDocFile is"+pdfDocFile);
InputStream iStream= new FileInputStream(WordDocFile);
OutputStream os = new FileOutputStream(pdfDocFile);
org.apache.poi.xwpf.usermodel.XWPFDocument document=new org.apache.poi.xwpf.usermodel.XWPFDocument(iStream);
oLog.error("Loaded XWPFDocument");
org.apache.poi.xwpf.converter.pdf.PdfOptions options= org.apache.poi.xwpf.converter.pdf.PdfOptions.create() ;
org.apache.poi.xwpf.converter.pdf.PdfConverter.getInstance().convert(document,os,options);
iStream.close();
os.close();
return "Success";
}
catch(Exception e)
{
e.printStackTrace();
oLog.error("print exception"+e);
return "FAIL";
}
SampleCode2 using Docx4j
try
{ final org.docx4j.wml.ObjectFactory objectFactory = new org.docx4j.wml.ObjectFactory();
String WordDocFile= "C:\\PRPCPersonalEdition\\tomcat\\TestDocument.docx";
String pdfDocFile="C:\\PRPCPersonalEdition\\tomcat\\TestDocument.pdf";
InputStream iStream= new FileInputStream(WordDocFile);
org.docx4j.openpackaging.packages.WordprocessingMLPackage pack = org.docx4j.openpackaging.packages.WordprocessingMLPackage.load(iStream);
org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart docPart = pack.getMainDocumentPart();
OutputStream os = new FileOutputStream(pdfDocFile);
org.docx4j.Docx4J.toPDF(pack,os);
iStream.close();
os.close();
return "Success";
}
catch(Exception e)
{
e.printStackTrace();
oLog.error("print exception"+e);
return "FAIL";
}
#Sample Code 3 using itext
try
{
java.util.List lstInputStream = new java.util.ArrayList < java.io.InputStream > ();
oLog.error("function PDF iText begin");
String WordDocFile= "C:\PRPCPersonalEdition\tomcat\DraftMin.docx";
String pdfDocFile="C:\PRPCPersonalEdition\tomcat\DraftMinItext12.pdf";
InputStream iStream= new FileInputStream(WordDocFile);
oLog.error("Read Input file"+iStream);
java.io.InputStream isCurrentStream = null;
OutputStream os = new FileOutputStream(pdfDocFile);
java.io.ByteArrayOutputStream osCurrentStream = null;
org.apache.poi.xwpf.usermodel.XWPFDocument document=new org.apache.poi.xwpf.usermodel.XWPFDocument(iStream);
fr.opensagres.poi.xwpf.converter.pdf.PdfOptions options = fr.opensagres.poi.xwpf.converter.pdf.PdfOptions.create();
fr.opensagres.poi.xwpf.converter.pdf.PdfConverter.getInstance().convert(document,(java.io.OutputStream)osCurrentStream, options);
com.itextpdf.text.Document finalDocument = new com.itextpdf.text.Document();
finalDocument.addAuthor("Your Corporation");
finalDocument.addCreationDate();
finalDocument.addProducer();
finalDocument.addCreator("System");
finalDocument.addTitle("Your Corporation");
finalDocument.setPageSize(com.itextpdf.text.PageSize.A4);
com.itextpdf.text.pdf.PdfCopy copy1 = new com.itextpdf.text.pdf.PdfCopy(finalDocument, (java.io.OutputStream) os);
finalDocument.open();
PRFile file = new PRFile("C:\PRPCPersonalEdition\tomcat\Savepdf.pdf");
PROutputStream prOS = new PROutputStream(file);
prOS.write(osCurrentStream.toByteArray());
oLog.debug("file write");
prOS.close();
PRInputStream prIS = new PRInputStream(file);
oLog.debug("file read");
isCurrentStream = (java.io.InputStream) prIS;
oLog.debug("casting to java.io.InputStream");
file.delete();
lstInputStream.add(isCurrentStream);
java.util.Iterator < java.io.InputStream > pdfIterator = lstInputStream.iterator();
while (pdfIterator.hasNext()) {
java.io.InputStream pdf = pdfIterator.next();
com.itextpdf.text.pdf.PdfReader.unethicalreading = true;
com.itextpdf.text.pdf.PdfReader readingpdf = new com.itextpdf.text.pdf.PdfReader(pdf);
int n = readingpdf.getNumberOfPages();
for ( int i=1;i<n;i++)
{
oLog.error("Entered in loop"+i);
copy1.addPage(copy1.getImportedPage(readingpdf, i));
oLog.error("Read Page n : "+i);
}
}
finalDocument.close();
iStream.close();
os.close();
return "Success";
}
catch(Exception e)
{
e.printStackTrace();
oLog.error("print exception"+e);
return "FAIL";
}

Webdings font characters not extracted using pdfbox

I am using pdfbox to get the names of all fonts that are used in a pdf.
So far it was working well. However, I recently came across a pdf that has 'Webdings' font. PDFBox was not able to identify it.Could anyone help please.
This is the code I have used:
public static Set<String> extractFonts(String pdfPath) throws IOException
{
PDDocument doc = PDDocument.load(new File(pdfPath));
PDPageTree pages = doc.getDocumentCatalog().getPages();
Set<String> fontSet = new HashSet<String>();
try{
for(PDPage page:pages){
PDResources res = page.getResources();
for (COSName fontName : res.getFontNames())
{
PDFont font = res.getFont(fontName);
if(font != null){
String fontUsedName = font.getName();
if(fontUsedName.contains("+")) {
fontUsedName = fontUsedName.substring(fontUsedName.indexOf("+")+1, fontUsedName.length());
}
fontSet.add(fontUsedName);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(fontSet);
return fontSet;
}
I was able to know that the font 'Webdings' is present from the File-> Properties->Fonts option in Adobe Reader

PDF setting that does not allow changes after signing

So i came across an interesting problem. So I know that in itext/itextsharp when you are signing has a setting on the PdfSignatureAppearance that you can set the CertificationLevel, and that works as expected, but recently i came across the problem where I am signing a document where the first signature in that document is signed wit PdfSignatureAppearance.CERTIFIED_FORM_FILLING, thus allowing me to add/sign signatures aftwards using (PdfSignatureAppearance.NOT_CERTIFIED) which act as approval signatures.
So the reason I am asking the question is that i came across a problem where i have a document with existing signature fields in the document, I sign the first signature with PdfSignatureAppearance.CERTIFIED_FORM_FILLING and the signatures after that with PdfSignatureAppearance.NOT_CERTIFIED, but when i sign the second signature field, the first signature field becomes invalid.
This document I am using was created using FoxitPro, but if I do the exact same thing in Adobe DC Pro it works as expected.
Any advice would be appreciated.
Here is the code i use for signing a pdf document, its only the signer class so other objects and references to this class will be missing.
public byte[] Sign(SignRequest request)
{
request.Document = SaveDocumentChanges(new SaveRequest
{
Document = request.Document,
FormFields = request.FormFields,
SigningBlocks = request.SigningBlocks
}, request.Information);
return SignDocument(request.Certificate, request.Information, request.SigningBlocks, request.SignatureImages, request.Document, request.IsFinalSignature);
}
private byte[] AddFormFields(List<FormField> formFields, byte[] document)
{
for (int i = 0; i < formFields.Count; i++)
{
using (MemoryStream outputStream = new MemoryStream())
{
using (PdfReader reader = new PdfReader(document))
{
using (PdfStamper stamper = CreatePdfStamper(reader, outputStream, false))
{
if (!DoesFormFieldExist(reader, formFields[i].Name))
{
CreateFormField(reader, stamper, formFields[i]);
}
else
{
UpdateFormField(stamper, formFields[i]);
}
}
}
document = outputStream.ToArray();
}
}
return document;
}
private byte[] AddMetaData(SigningInformation information, byte[] document)
{
if (information.CustomProperties != null && information.CustomProperties.Any())
{
using (MemoryStream outputStream = new MemoryStream())
{
using (PdfReader reader = new PdfReader(document))
{
using (PdfStamper stamper = CreatePdfStamper(reader, outputStream, false))
{
Dictionary<string, string> currentProperties = reader.Info;
foreach (string key in information.CustomProperties.Keys)
{
AddMetaDataAddDictionaryValue(currentProperties, key, information.CustomProperties[key]);
}
AddMetaDataAddDictionaryValue(currentProperties, "Producer", "Signisure");
AddMetaDataAddDictionaryValue(currentProperties, "Creator", "Signisure");
AddMetaDataAddDictionaryValue(currentProperties, "Author", "Signisure");
stamper.MoreInfo = currentProperties;
}
}
return outputStream.ToArray();
}
}
return document;
}
private void AddMetaDataAddDictionaryValue(Dictionary<string, string> dictionary, string key, string value)
{
if (dictionary.ContainsKey(key))
{
dictionary[key] = value;
}
else
{
dictionary.Add(key, value);
}
}
private void AddMetaDataAddDictionaryValue(PdfDictionary dictionary, PdfName key, PdfObject value)
{
if (!dictionary.Keys.Contains(key))
{
dictionary.Put(key, value);
}
}
private byte[] AddSignatureFields(List<SigningBlock> signingBlocks, byte[] document)
{
for (int i = 0; i < signingBlocks.Count; i++)
{
using (MemoryStream outputStream = new MemoryStream())
{
using (PdfReader reader = new PdfReader(document))
{
using (PdfStamper stamper = CreatePdfStamper(reader, outputStream, false))
{
if (!DoesSignatureFieldExist(reader, signingBlocks[i].Name))
{
CreateSignatureField(stamper, signingBlocks[i]);
}
}
}
document = outputStream.ToArray();
}
}
return document;
}
private void CreateFormField(PdfReader reader, PdfStamper stamper, FormField formField)
{
TextField field = new TextField(stamper.Writer, new Rectangle(formField.X, formField.Y, formField.X + formField.Width, formField.Y + formField.Height), formField.Name);
field.Text = formField.Value;
field.Font = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, BaseFont.EMBEDDED);
field.FontSize = 12;
field.Options = TextField.READ_ONLY;
stamper.AddAnnotation(field.GetTextField(), formField.Page);
}
private PdfSignatureAppearance CreatePdfAppearance(PdfStamper stamper, SigningInformation information, string location, bool certify)
{
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
CreatePdfAppearanceCertifyDocument(appearance, certify);
if (information != null)
{
appearance.Location = location != String.Empty ? String.Format("{0} ({1})", location, information.IPAddress) : information.IPAddress;
appearance.Reason = information.SignatoryReason;
appearance.Contact = String.Format("{0} ({1})", information.Signatory, information.SignatoryEmail);
}
return appearance;
}
private void CreatePdfAppearanceCertifyDocument(PdfSignatureAppearance appearance, bool certify)
{
if (certify)
{
appearance.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS;
}
else
{
appearance.CertificationLevel = PdfSignatureAppearance.NOT_CERTIFIED;
}
}
private PdfStamper CreatePdfStamper(PdfReader reader, MemoryStream outputStream, bool isSignature)
{
if (CreatePdfStamperIsPDFADocument(reader))
{
if (isSignature)
{
return PdfAStamper.CreateSignature(reader, outputStream, _pdfVersion, null, true, PdfAConformanceLevel.PDF_A_1A);
}
else
{
return new PdfAStamper(reader, outputStream, _pdfVersion, true, PdfAConformanceLevel.PDF_A_1A);
}
}
else
{
if (isSignature)
{
return PdfStamper.CreateSignature(reader, outputStream, _pdfVersion, null, true);
}
else
{
return new PdfStamper(reader, outputStream, _pdfVersion, true);
}
}
}
private bool CreatePdfStamperIsPDFADocument(PdfReader reader)
{
if (reader.Metadata != null && reader.Metadata.Length > 0)
{
IXmpMeta xmpMeta = XmpMetaParser.Parse(reader.Metadata, null);
IXmpProperty pdfaidConformance = xmpMeta.GetProperty(XmpConst.NS_PDFA_ID, "pdfaid:conformance");
IXmpProperty pdfaidPart = xmpMeta.GetProperty(XmpConst.NS_PDFA_ID, "pdfaid:part");
if (pdfaidConformance == null || pdfaidPart == null)
{
return false;
}
return true;
}
return false;
}
private void CreateSignatureField(PdfStamper stamper, SigningBlock signingBlock)
{
if (signingBlock == null)
{
return;
}
PdfFormField signatureField = PdfFormField.CreateSignature(stamper.Writer);
signatureField.SetWidget(new Rectangle(signingBlock.X, signingBlock.Y, signingBlock.X + signingBlock.Width, signingBlock.Y + signingBlock.Height), null);
signatureField.Flags = PdfAnnotation.FLAGS_PRINT;
signatureField.FieldName = signingBlock.Name;
signatureField.Page = signingBlock.Page;
signatureField.Put(PdfName.CONTENTS, new PdfString(String.Empty));
CreateSignatureFieldAddLockProperties(signatureField, signingBlock, stamper);
stamper.AddAnnotation(signatureField, signingBlock.Page);
}
private void CreateSignatureFieldAddLockProperties(PdfFormField signatureField, SigningBlock signingBlock, PdfStamper stamper)
{
if (signingBlock.LinkedFormFields != null && signingBlock.LinkedFormFields.Count > 0)
{
PdfSigLockDictionary lockDictionary = new PdfSigLockDictionary(PdfSigLockDictionary.LockAction.INCLUDE, signingBlock.LinkedFormFields.ToArray());
signatureField.Put(PdfName.LOCK, stamper.Writer.AddToBody(lockDictionary).IndirectReference);
}
}
private bool DoesFormFieldExist(PdfReader reader, string formFieldName)
{
if (String.IsNullOrWhiteSpace(formFieldName))
{
return false;
}
return reader.AcroFields.Fields.Where(vp => vp.Key == formFieldName).Any();
}
private bool DoesSignatureFieldExist(PdfReader reader, string signatureFieldName)
{
if (String.IsNullOrWhiteSpace(signatureFieldName))
{
return false;
}
return reader.AcroFields.DoesSignatureFieldExist(signatureFieldName);
}
private AcroFields.FieldPosition GetAcroFieldByName(PdfStamper stamper, string signatureBlockName)
{
return stamper.AcroFields.GetFieldPositions(signatureBlockName).FirstOrDefault();
}
private List<string> GetAllSignatureFieldNames(PdfReader reader)
{
List<string> signatureFields = new List<string>();
signatureFields.AddRange(reader.AcroFields.GetBlankSignatureNames());
signatureFields.AddRange(reader.AcroFields.GetSignatureNames());
return signatureFields;
}
private void GetDocumentFormFieldsBuildFormFields(List<FormField> formFields, PdfReader reader, PdfStamper stamper)
{
List<string> signatureFields = GetAllSignatureFieldNames(reader);
foreach (KeyValuePair<string, AcroFields.Item> field in reader.AcroFields.Fields)
{
string fieldName = field.Key.ToString();
if (!signatureFields.Where(signatureFieldName => signatureFieldName == fieldName).Any())
{
string fieldValue = reader.AcroFields.GetField(field.Key.ToString());
AcroFields.FieldPosition formFieldPosition = GetAcroFieldByName(stamper, fieldName);
formFields.Add(GetDocumentFormFieldsBuildFormFieldsCreateField(formFieldPosition, fieldName, fieldValue));
}
}
}
private FormField GetDocumentFormFieldsBuildFormFieldsCreateField(AcroFields.FieldPosition formFieldPosition, string fieldName, string fieldValue)
{
return new FormField
{
Height = (int)formFieldPosition.position.Height,
Name = fieldName,
Page = formFieldPosition.page,
Width = (int)formFieldPosition.position.Width,
X = (int)formFieldPosition.position.Left,
Y = (int)formFieldPosition.position.Top,
Value = fieldValue
};
}
private void GetDocumentSignatureBlocksBuildSignatureBlocks(List<SigningBlock> signatureBlocks, List<string> signatureBlockNames, PdfReader reader, PdfStamper stamper, bool isSigned)
{
foreach (string signatureBlockName in signatureBlockNames)
{
AcroFields.FieldPosition signatureFieldPosition = GetAcroFieldByName(stamper, signatureBlockName);
signatureBlocks.Add(GetDocumentSignatureBlocksBuildSignatureBlocksCreateBlock(signatureFieldPosition, signatureBlockName, isSigned));
}
}
private SigningBlock GetDocumentSignatureBlocksBuildSignatureBlocksCreateBlock(AcroFields.FieldPosition signatureFieldPosition, string fieldName, bool isSigned)
{
return new SigningBlock
{
Height = (int)signatureFieldPosition.position.Height,
Name = fieldName,
Page = signatureFieldPosition.page,
Width = (int)signatureFieldPosition.position.Width,
X = (int)signatureFieldPosition.position.Left,
Y = (int)signatureFieldPosition.position.Top,
IsSigned = isSigned
};
}
private string GetFormFieldValueForName(PdfStamper stamper, string formFieldName)
{
AcroFields formFields = stamper.AcroFields;
return formFields.GetField(formFieldName);
}
private byte[] GetSignatureImage(List<MemberItemSignature> signatureImages, string signingBlockName)
{
MemberItemSignature signature = signingBlockName.Contains("Initial") ? signatureImages.Where(image => image.Use == SignatureUses.Initial).FirstOrDefault() : signatureImages.Where(image => image.Use == SignatureUses.Signature).FirstOrDefault();
if (signature != null)
{
return signature.Image;
}
return null;
}
private byte[] SaveDocumentChanges(SaveRequest request, SigningInformation information)
{
request.Document = AddMetaData(information, request.Document);
request.Document = AddFormFields(request.FormFields, request.Document);
request.Document = AddSignatureFields(request.SigningBlocks, request.Document);
return request.Document;
}
private byte[] SignDocument(Certificate certificate, SigningInformation information, List<SigningBlock> signingBlocks, List<MemberItemSignature> signatureImages, byte[] document, bool isFinalSignature)
{
for (int i = 0; i < signingBlocks.Count; i++)
{
document = SignDocumentSignSignatureField(certificate, information, signingBlocks[i], signatureImages, document, true);
}
if (isFinalSignature)
{
return SignDocumentLTVVerification(certificate, document);
}
return document;
}
private byte[] SignDocumentLTVVerification(Certificate certificate, byte[] document)
{
using (MemoryStream outputStream = new MemoryStream())
{
using (PdfReader reader = new PdfReader(document))
{
using (PdfStamper stamper = PdfStamper.CreateSignature(reader, outputStream, '\0', null, true))
{
SignDocumentSigningBlockAddLTVVerification(stamper, certificate);
}
}
return outputStream.ToArray();
}
}
private void SignDocumentSigningBlock(SigningComponents components, SigningInformation information, SigningBlock block, PdfSignatureAppearance appearance, PdfStamper stamper, byte[] signatureImage)
{
appearance.SetVisibleSignature(block.Name);
SignDocumentSigningBlockWithImage(signatureImage, appearance);
SignDocumentSigningBlockWithText(appearance, information, appearance.SignDate);
if (components.Certificate != null)
{
using (RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)components.Certificate.PrivateKey)
{
PrivateKeySignature privateKeySignature = SignDocumentSigningBlockBuildDigestSigningMethod(information, rsa) as PrivateKeySignature;
SignatureHelper.Sign(appearance, privateKeySignature, components.CertificateChain, new List<ICrlClient> { components.CrlClient }, components.OcspClient, components.TimeStampingAuthority, Int32.Parse(_settingManager["DocumentSigningEstimatedDigestSize"]), CryptoStandard.CMS, SignDocumentSigningBlockCreateMetaData(information));
}
}
else
{
HSMExternalSignature hsmExternalSignature = SignDocumentSigningBlockBuildDigestSigningMethod(information, null) as HSMExternalSignature;
SignatureHelper.Sign(appearance, hsmExternalSignature, components.TimeStampingAuthority, Int32.Parse(_settingManager["DocumentSigningEstimatedDigestSize"]), CryptoStandard.CMS, SignDocumentSigningBlockCreateMetaData(information));
}
}
private void SignDocumentSigningBlockAddLTVVerification(PdfStamper stamper, Certificate certificate)
{
SigningComponents components = new SigningComponents(_settingManager, certificate);
LtvVerification ltvVerification = stamper.LtvVerification;
List<string> signatureFieldNames = stamper.AcroFields.GetSignatureNames();
PdfPKCS7 pkcs7 = stamper.AcroFields.VerifySignature(signatureFieldNames.Last());
if (pkcs7.IsTsp)
{
bool validationAddedSuccessfully = ltvVerification.AddVerification(signatureFieldNames.Last(), components.OcspClient, components.CrlClient, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.YES);
}
else
{
foreach (string name in stamper.AcroFields.GetSignatureNames())
{
bool validationAddedSuccessfully = ltvVerification.AddVerification(name, components.OcspClient, components.CrlClient, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.YES);
}
}
ltvVerification.Merge();
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
LtvTimestamp.Timestamp(appearance, components.TimeStampingAuthority, null);
}
private IExternalSignature SignDocumentSigningBlockBuildDigestSigningMethod(SigningInformation information, RSACryptoServiceProvider rsaCryptoProvider)
{
if (information.CertificateUse == CertificateUse.SignisureCertificate || rsaCryptoProvider == null)
{
return new HSMExternalSignature(_hsmService, _settingManager["DocumentSigningEncryptionHashAlgorithm"]);
}
else
{
return new PrivateKeySignature(DotNetUtilities.GetRsaKeyPair(rsaCryptoProvider).Private, _settingManager["DocumentSigningEncryptionHashAlgorithm"]);
}
}
private PdfDictionary SignDocumentSigningBlockCreateMetaData(SigningInformation information)
{
PdfDictionary signatureDictionary = new PdfDictionary();
if (!String.IsNullOrWhiteSpace(information.IdentificationInformation))
{
AddMetaDataAddDictionaryValue(signatureDictionary, new PdfName(".Signisure.IdentificationInformation"), new PdfString(information.IdentificationInformation));
}
if (!String.IsNullOrWhiteSpace(information.JuristicEntity))
{
AddMetaDataAddDictionaryValue(signatureDictionary, new PdfName(".Signisure.JuristicEntity"), new PdfString(information.JuristicEntity));
}
if (!String.IsNullOrWhiteSpace(information.Capacity))
{
AddMetaDataAddDictionaryValue(signatureDictionary, new PdfName(".Signisure.Capacity"), new PdfString(information.Capacity));
}
return signatureDictionary;
}
private void SignDocumentSigningBlockWithImage(byte[] signatureImage, PdfSignatureAppearance appearance)
{
if (signatureImage != null && signatureImage.Length > 0)
{
Image signatureImageInstance = Image.GetInstance(ImageHelper.FlattenImage(signatureImage));
appearance.Image = signatureImageInstance;
appearance.SignatureGraphic = signatureImageInstance;
}
}
private void SignDocumentSigningBlockWithText(PdfSignatureAppearance appearance, SigningInformation information, DateTime timestampDateTime)
{
BaseFont verdana = BaseFont.CreateFont(AssemblyDirectory + "\\Content\\Fonts\\Verdana\\Verdana.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
BaseFont helvetica = BaseFont.CreateFont(AssemblyDirectory + "\\Content\\Fonts\\Helvetica\\Helvetica.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
BaseFont comicSans = BaseFont.CreateFont(AssemblyDirectory + "\\Content\\Fonts\\ComicSans\\ComicSans.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
appearance.Layer2Text = SignDocumentSigningBlockWithTextBuildText(appearance, information, timestampDateTime);
appearance.Layer2Font = new Font(verdana);
}
private string SignDocumentSigningBlockWithTextBuildText(PdfSignatureAppearance appearance, SigningInformation information, DateTime timestampDateTime)
{
return String.Format("Signee: {0}\nSign date: {1}\nLocation: {2}\nReason: {3}", information.Signatory, timestampDateTime.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss zzz"), appearance.Location, appearance.Reason);
}
private byte[] SignDocumentSignSignatureField(Certificate certificate, SigningInformation information, SigningBlock signingBlock, List<MemberItemSignature> signatureImages, byte[] document, bool isVisible)
{
SigningComponents components = new SigningComponents(_settingManager, certificate);
using (MemoryStream outputStream = new MemoryStream())
{
using (PdfReader reader = new PdfReader(document))
{
using (PdfStamper stamper = CreatePdfStamper(reader, outputStream, true))
{
PdfSignatureAppearance appearance = CreatePdfAppearance(stamper, information, SignDocumentSignSignatureFieldBuildLocation(stamper, signingBlock), false);
SignDocumentSigningBlock(components, information, signingBlock, appearance, stamper, GetSignatureImage(signatureImages, signingBlock.Name));
}
}
return outputStream.ToArray();
}
}
private string SignDocumentSignSignatureFieldBuildLocation(PdfStamper stamper, SigningBlock signingBlock)
{
StringBuilder builder = new StringBuilder();
for (int index = 0; index < signingBlock.LinkedFormFields.Count; index++)
{
builder.Append(GetFormFieldValueForName(stamper, signingBlock.LinkedFormFields[index]));
if (index + 1 < signingBlock.LinkedFormFields.Count)
{
builder.Append(", ");
}
}
return builder.ToString();
}
private void UpdateFormField(PdfStamper stamper, FormField formField)
{
AcroFields formFields = stamper.AcroFields;
if (formField.Value != null && GetFormFieldValueForName(stamper, formField.Name) != formField.Value)
{
formFields.SetField(formField.Name, formField.Value);
formFields.SetFieldProperty(formField.Name, "setfflags", PdfFormField.FF_READ_ONLY, null);
}
}
}
}
Short answer:
If you sign a document with a certification signature with level PdfSignatureAppearance.CERTIFIED_FORM_FILLING, then you can add as many extra approval signatures as you want without breaking the original (or preceding) signatures.
Longer answer:
Nobody will believe you if you write:
I am trying to sign a document with PdfSignatureAppearance.CERTIFIED_FORM_FILLING first, that should allow me to add more signature fields, edit form fields or sign other signature fields, but instead it is invalidating my subsequent signature signing.
What you're saying here is wrong.
However, maybe you're not signing the PDF correctly. Allow me to repeat my short answer:
If you sign a document with a certification signature with level PdfSignatureAppearance.CERTIFIED_FORM_FILLING, then you can add as many extra approval signatures as you want without breaking the original (or preceding) signatures.
I am highlighting two concepts. A PDF can have at most one certification signature (aka author signature) and this signature should be the first signature in the document. A PDF can have several approval signatures (aka recipient signatures).
Maybe you are signing the document using a certification signature (I assume this is true because you talk about the certification level). And maybe you are trying to add a second certification signature. Obviously, this would break the signatures in the PDF because the PDF specification only allows a single certification signature.
Maybe you're problem is solved by adding approval signatures instead of certification signatures.

Add a Bitmap image in a PDF document in Android

please, how can i directly pass a bitmap image to a pdf file. I have made a graph with GraphView and at the end i convert it to Bitmap, inside an OnClickListener:
write.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0) {
Bitmap bitmap;
graph.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(graph.getDrawingCache());
graph.setDrawingCacheEnabled(false);
String filename = "imagen";
FileOperations fop = new FileOperations();
fop.write(filename, bitmap);
if (fop.write(filename,bitmap)) {
Toast.makeText(getApplicationContext(),
filename + ".pdf created", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(getApplicationContext(), "I/O error",
Toast.LENGTH_SHORT).show();
}
}
});
The problem is that in the class FileOperations:
public FileOperations() {
}
public Boolean write(String fname, Bitmap bm) {
try {
String fpath = "/sdcard/" + fname + ".pdf";
File file = new File(fpath);
if (!file.exists()) {
file.createNewFile();
}
Document document = new Document();
PdfWriter.getInstance(document,
new FileOutputStream(file.getAbsoluteFile()));
document.open();
String filename = bm.toString();
com.itextpdf.text.Image image =com.itextpdf.text.Image.getInstance(filename);
document.add(image);
document.add(new Paragraph("Hello World2!"));
// step 5
document.close();
Log.d("Suceess", "Sucess");
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
}
I want to know how can i pass the bitmap Image to add it in the pdf document, i do this but i think this works only when i give it a path.
String filename = bm.toString();
com.itextpdf.text.Image image =com.itextpdf.text.Image.getInstance(filename);
I just solve it:
document.open();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100 , stream);
Image myImg = Image.getInstance(stream.toByteArray());
myImg.setAlignment(Image.MIDDLE);
document.add(myImg);
in the FileOperations class