PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Sat Apr 20, 2019 2:29 pm

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Tue Nov 22, 2016 5:04 am 
Offline

Joined: Tue Nov 15, 2016 3:58 pm
Posts: 8
Using the below packages:

<package id="PDFsharp-MigraDoc-gdi" version="1.50.4000-beta3b" targetFramework="net45" />

I am using PdfSharp apis, not the MigraDoc. I am form filling a pdf based on a template. I am replacing iTextSharp with PDFSharp.

The textboxes are filled in correctly, but when viewing the pdf in Adobe, the textbox font is smaller (and may be a different font). Then once I set focus to the textbox does it change to the correct font, or to a more preferable font. When I added the below, it fixes the behavior of focus/not focus, and the font is correct.

Code:
if (form.Elements.ContainsKey(PdfAcroForm.Keys.NeedAppearances))
            {
                form.Elements[PdfAcroForm.Keys.NeedAppearances] = new PdfSharp.Pdf.PdfBoolean(true);
            }
            else
            {
                form.Elements.Add(PdfAcroForm.Keys.NeedAppearances, new PdfSharp.Pdf.PdfBoolean(true));
            }


However, when it is opened in Adobe, Adobe modifies it to remove it and requires save on close, even if just viewing it. A post for iTextSharp mentioned having to do this as well.
Code:
form.Elements.Remove("/NeedAppearances");


But, then it continues to have same behavior on focus/not focus.

Using a tool PdfExplorer to compare the adobe prompted/saved version, with the removed "NeedAppearances" version, it has added base fonts to AcroForms -> DR -> Font for "TimesNewRomanPSMT" and "TimesNewRoman". I do not see any other changes at this time between the two versions. iTextSharp also seems to have this, though the structure is not quite the same. In the case of Adobe, it looks like it is embedding it and making the files size increase an significant amount, because there is a FontFile element. With iTextSharp, it does not look to be embedded.

So, in order to add the base fonts using PDFSharp, do I need to do something like this or is there an easier way? I have been seeing references to FontResolver, but it is described to use it for WPF or if it is coming from a non-installed font, which neither is the case. I would figure something like PdfTrueTypeFont would be available as PdfItem, but even PdfTrueTypeFont is internal.

Code:
PdfDictionary dr = form.Elements.GetDictionary("/DR");
                PdfDictionary fonts = dr.Elements.GetDictionary("/Font");
                if (fonts == null)
                {
                    fonts = new PdfDictionary();
                    dr.Elements.Add("/Font", new PdfDictionary());
                }
                if (!fonts.Elements.ContainsKey("/TimesNewRomanPSMT"))
                {
                    //var timeNewRoman = new PdfDictionary();
                    //timeNewRoman.Elements.Add("/LastChar", new PdfInteger(255));
                    //timeNewRoman.Elements.Add("/Encoding", new PdfString("/WinAnsiEncoding"));
                    //timeNewRoman.Elements.Add("/BaseFont", new PdfString("/TimesNewRoman"));
                    //timeNewRoman.Elements.Add("/Type", new PdfString("/Font"));
                    //var fontDescriptor = new PdfDictionary();

                    //timeNewRoman.Elements.Add("/FontDescriptor", new PdfFontDescriptor()("/Font"));
                    //timeNewRoman.Elements.Add("/Subtype", new PdfString("/TrueType"));
                    //timeNewRoman.Elements.Add("/Widths", new PdfArray());
                    //timeNewRoman.Elements.Add("/FirstChar", new PdfInteger(0));

                    ////  fonts.Elements.Add("/TimesNewRomanPSMT", timeNewRoman);
                   
                }


EDIT:


Thanks,


Attachments:
File comment: The adobe structure after saving when prompted by adobe so that it can remove the /NeedAppearances. In the PdfSharp Structure, there is only ZaDb, Helv, and ArialRoundedMTBold.
Acrobat Structure.png
Acrobat Structure.png [ 30.55 KiB | Viewed 2679 times ]
File comment: Focused font that I believe is Times New Roman. Specified on the field itself Field->DA->TimesNewRomanPSMT 12.00 Tf 0 g
Focused Font - Times New Roman.png
Focused Font - Times New Roman.png [ 2.57 KiB | Viewed 2679 times ]
File comment: Not Focus font that I believe is Helvetica. Helvetica is in the list of basefonts, however, it is not the font that shows on the field Field->DA->TimesNewRomanPSMT 12.00 Tf 0 g
Not Focused Font - Helvetica I believe.png
Not Focused Font - Helvetica I believe.png [ 1.98 KiB | Viewed 2679 times ]
Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 23, 2016 8:11 pm 
Offline

Joined: Tue Nov 15, 2016 3:58 pm
Posts: 8
Ok, so I have figured out what my problem was. So initially, I had set the PDFTextField.Font, but it was not working. I had also tried setting the /DA of the PDFTextField, but it was not working. However, the reason PDFTextField.Font was not working was because I was setting the Font after the Text. Text does not get refreshed from font change, so it looked to be using the "Courier New" default. I figured this out by debugging the PDFSharp source.

PDFSharp does not look to include the baseFonts, it just draws a string. It is about 90KB bigger than what it is supposed to be, but I will look at that at a later time.

Summary:
1. When setting Font, ForeColor, and BackColor after Text, it does not refresh it. So set them beforehand.
2. PDFSharp does not use the font that is already included e.g. Field->DA->TimesNewRomanPSMT 12.00 Tf 0 g

EDIT:

Since PDFSharp is not doing anything with Field->DA and not doing anything with BaseFonts, there still is a noticeable onfocus/not focus. The above fix/change does help with the non focus font. However, the focused font is Times New Roman, based on copying the text into word and comparison with fonts. When I set Field->DA, the text is no longer selectable, as if it has been burned into the graphics. This may be due to Adobe thinking there is an error, or maybe something is not set when changing DA. Here is an example:

Code:
//Tried
field.Elements["/DA"] = new PdfString("Helv 12.00 Tf 0 g")

//Tried
field.Elements["/DA"] = new PdfString("Helvatica 12.00 Tf 0 g")


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 26, 2016 7:01 am 
Offline

Joined: Tue Nov 15, 2016 3:58 pm
Posts: 8
Ok, so I was able to fix the on focus issue by using the below. I am not sure the difference between what I was doing in above post, as I would assume it to be the same end result, but it works. I chose to do it this way because when Text is set, it uses SetString.

textbox.Elements.SetString(PdfTextField.Keys.DA, "/Helv 12 Tf 0 g");


So this concludes the font issue.

Summary:
1. When setting Font, ForeColor, and BackColor after Text, it does not refresh it. So set them beforehand.
2. PDFSharp does not use the font that is already included e.g. Field->DA->TimesNewRomanPSMT 12.00 Tf 0 g
3. It looks like on focus font, and non-focus font, are different. Use PDFTextField.Text to set the non-focus font. Use above SetString to set the focus font.


Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 09, 2018 6:59 am 
Offline

Joined: Sat Jun 09, 2018 6:46 am
Posts: 1
Hey - thanks for the great post, it really helped me with the font changes between view and edit. However I can't seem to Get PDFSharp (v 1.50.4845-RC2a) to add a font entry to the main Acroform DR Font node. Individual fields have the font correctly specified in their DA fields, but google chrome is not rendering the form fields correctly until the overall form DR field is set. (at least that's what I think the problem is because once I set the font manually using a dekstop tool the font shows up there and everything works).

How were you able to get the DR node to be updated in your code? Did you wind up having to use a modified version of the process in your original post, or did it work using PDFSharp form field operations? I set the both of the form Field font descriptors before updating the field text (via the value property) as you suggest.

Thanks for your help.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 07, 2019 7:41 pm 
Offline

Joined: Tue Nov 15, 2016 3:58 pm
Posts: 8
Peter,

Sorry, its actually been a while since I looked at it, and I am not too familiar with PDFs in general, but am ok with debugging and figuring things out. In regards, main form DR field, I don't think I was able to set the main form font based on my recollection, which is why I was setting the individual controls font. Really, I would have to look at it again to see. The only reason I saw your post is because I am updating my project to a new version and comparing files and needed to know which files i changed.

EDIT:
Another consideration, is that I may have not tried changing the main font because I wasn't sure the behavior it would have on the rest of the PDF, and I needed the fonts to stay the same where possible.


Quote:
How were you able to get the DR node to be updated in your code? Did you wind up having to use a modified version of the process in your original post, or did it work using PDFSharp form field operations? I set the both of the form Field font descriptors before updating the field text (via the value property) as you suggest.


Most of what I was doing was modified. https://github.com/zaryk/PDFsharp is the git for the two posts i was doing that involves modifications to PDFSharp itself, and then I have a PDFHelper that when setting the value of the field:

-- Show Appearances:
Code:
public bool ShowAppearances
        {
            get
            {
                return showAppearances;
            }
            set
            {
                showAppearances = value;
                if (value)
                {
                    if (form.Elements.ContainsKey(PdfAcroForm.Keys.NeedAppearances))
                    {
                        form.Elements[PdfAcroForm.Keys.NeedAppearances] = new PdfSharp.Pdf.PdfBoolean(true);
                    }
                    else
                    {
                        form.Elements.Add(PdfAcroForm.Keys.NeedAppearances, new PdfSharp.Pdf.PdfBoolean(true));
                    }
                }
            }
        }


Code:
  public void SetPdfField(string field, object value, XFont font, XStringFormat format)
        {
            var pdfField = form.Fields[field];
            if (value != null && !string.IsNullOrWhiteSpace(field) &&
                pdfField != null)
            {
                var formmatted = value.ToString();


                if (pdfField is PdfCheckBoxField)
                {
                    var checkbox = ((PdfCheckBoxField)form.Fields[field]);
                    checkbox.Checked = Convert.ToBoolean(formmatted);
                }
                else if (pdfField is PdfTextField)
                {
                    if (value is bool)
                    {
                        formmatted = (bool)value ? "1" : "";
                    }
                    var textbox = ((PdfTextField)form.Fields[field]);
                   
                    if(this.AcroFormFont != null)
                    {
                       
                       
                        textbox.Font = AcroFormFont;
                        //HACK - Figure out another built in way, or wait for them to add a builtin way.
                        textbox.Elements.SetString(PdfTextField.Keys.DA, "/Helv 12 Tf 0 g");
                    }
                    else if(font != null)
                    {
                        textbox.Font = font;
                    }

                    if(format != null)
                    {
                        textbox.Alignment = format;
                    }

                    //if (flags.HasFlag(PdfAcroFieldFlags.Multiline))
                    //{
                    //    formatte
                    //}
                    //PdfHelper.RestGenericTypographic();
                    // textbox.BackColor = XColor.FromKnownColor(XKnownColor.Red);


                    if (textbox.MultiLine)
                    {
                        if (XStringFormats.Equals(textbox.Alignment, XStringFormats.TopLeft))
                        {
                            textbox.LeftMargin = 2;
                            textbox.TopMargin = -6;
                            textbox.RightMargin = 0;
                            textbox.BottomMargin = 0;
                        }
                        else if (XStringFormats.Equals(textbox.Alignment, XStringFormats.TopCenter))
                        {

                        }
                        else if (XStringFormats.Equals(textbox.Alignment, XStringFormats.TopRight))
                        {

                        }

                    }
                    else
                    {
                        if (XStringFormats.Equals(textbox.Alignment, XStringFormats.CenterLeft))
                        {
                           textbox.LeftMargin = 2;
                            textbox.TopMargin = .25;
                            textbox.RightMargin = 0;
                            textbox.BottomMargin = 0;
                        }
                        else if (XStringFormats.Equals(textbox.Alignment, XStringFormats.Center))
                        {
                            textbox.TopMargin = .25;
                        }
                        else if (XStringFormats.Equals(textbox.Alignment, XStringFormats.CenterRight))
                        {
                            textbox.LeftMargin = 0;
                            textbox.TopMargin = .25;
                            textbox.RightMargin = -2;
                            textbox.BottomMargin = 0;

                        }
                    }

                   
                    textbox.Text = formmatted;
                    //PdfHelper.RestGenericTypographic();
                }

            }
        }


usage is something like this:

Code:
using (PdfHelper inputDocument = new PdfHelper(DocumentType.LowLevel, templatePath, PdfDocumentOpenMode.Modify))
                        {
                            inputDocument.Version = 17;
                            inputDocument.Flatten = true;
                            inputDocument.RemoveExecutables = true;
                            inputDocument.RemoveJavascript = true;
                            inputDocument.AcroFormFont = new XFont("Helvetica", 12, XFontStyle.Regular, new XPdfFontOptions(PdfFontEncoding.WinAnsi));
                            inputDocument.ShowAppearances = true;

                            XStringFormat format = new XStringFormat();
                            format.Alignment = XStringAlignment.Center;
                            format.LineAlignment = XLineAlignment.Center;
                            inputDocument.SetPdfField("Caption", caption.StripTags().DecodeTags());
                            inputDocument.SetPdfField("Submitted_by", string.Format("{0} {1}", user.Ctc_FirstName, user.Ctc_LastName));
                            inputDocument.SetPdfField("Address1", user.Ctc_Address1);

Thanks,


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group