PDFsharp & MigraDoc Forum
https://forum.pdfsharp.net/

How to set default print scaling to "None"?
https://forum.pdfsharp.net/viewtopic.php?f=2&t=936
Page 1 of 1

Author:  Remis [ Wed Nov 11, 2009 12:22 pm ]
Post subject:  How to set default print scaling to "None"?

Hi,

does someone know how to generate PDF document with default print scaling "None"?

PDFsharp/MigraDoc Foundation
GDI+ build
v 1.30 (PDFsharp - 1.3.1684.0, MigraDoc.DocumentObjectModel.dll - 1.2.2961.0)

I generate PDF, open it in Adobe Reader 9.2.0, open Print dialog. Page Scaling options available there are:
    None
    Fit to Printable Area
    Shrink to Printable Area
    Multiple pages per sheet
    Booklet Printing

"Fit to Printable Area" is default and I don't know how to set it to desired "None". This is important in mapping applications to display a precise scale bar.
I use PrintScaling setting in ViewerPreferences = "None". Maybe AcroReader 9 ignores this setting while print dialog in Reader 7,8 works as expected?

Code:
      private void GenerateScaleNoneDoc()
      {
         // Create a simple MigrDoc document
         Document document = new Document();
         document.AddSection().AddParagraph("Some text");

         // Render it as PDF, param true for Unicode
         PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(true, PdfFontEmbedding.Always);
         pdfRenderer.Document = document;
         pdfRenderer.RenderDocument();

         // Set PDF-specific settings
         PdfDocument pdfDocument = pdfRenderer.PdfDocument;
         pdfDocument.PageLayout = PdfPageLayout.SinglePage;
         pdfDocument.PageMode = PdfPageMode.UseNone;

         // Doc from internals: PdfSharp.Pdf.PdfViewerPreferences.Keys.PrintScaling:
         //[KeyInfo(KeyType.Name | KeyType.Optional)]
         //public const string PrintScaling = "/PrintScaling";
         //
         // (Optional; PDF 1.6) The page scaling option to be selected when a print dialog is
         // displayed for this document. Valid values are None, which indicates that the print
         // dialog should reflect no page scaling, and AppDefault, which indicates that
         // applications should use the current print scaling. If this entry has an unrecognized
         // value, applications should use the current print scaling.
         // Default value: AppDefault.
         // Note: If the print dialog is suppressed and its parameters are provided directly
         // by the application, the value of this entry should still be used.

         // ?Doesn't work on Reader v9?
         // The same valueas are mentioned here: http://www.pdftron.com/kb/questions.php?questionid=759

         // Avoid "Fit to page" automatic behaviour, set PrintScaling property.
         // PrintScaling is supported from Acrobat 7.x (1.6)
         pdfDocument.Version = 16;
         pdfDocument.ViewerPreferences.Elements.SetString("/PrintScaling", "None");

         // Save the PDF to a file:
         string filename = "Default-Print-Scale-None.pdf";
         pdfDocument.Save(filename);

         // Open AcroReader
         Process.Start(filename);
      }

Author:  m.slingerland [ Fri Feb 11, 2011 9:52 am ]
Post subject:  Re: How to set default print scaling to "None"?

Hi,

Did you already find a solution for this?

Kind regards,


Matthijs

Author:  Remis [ Tue Feb 22, 2011 7:57 am ]
Post subject:  Re: How to set default print scaling to "None"?

No but it was OK as it was, just "not perfect" :)

Author:  AzStafford [ Thu Sep 27, 2012 8:29 pm ]
Post subject:  Re: How to set default print scaling to "None"?

I ran into this same problem yesterday. After much research, I found:
1) PDF v1.7 has been "superseded" by ISO 32000-1:2008
2) Using the PDFSharp option of ViewerPreferences.Elements.SetString("/PrintScaling", "None") would generate the following ASCII text within the PDF
Code:
/PrintScaling(None)

3) The new version of PDF expects ASCII text like the following:
Code:
/Enforce(PrintScaling)/PrintScaling/None


As a result, I devised that if I use a little trickery, I can use the PDFSharp option to my advantage in order to create an ASCII string close to my desired output. Then, after capturing the bytes of the PDF document, I can replace them with the desired ASCII string. My generic approach was the following:

Code:
PdfDocument doc = new PdfDocument();
//Make PDF to have a setting to force paper printing to use "Actual Size"
//as scaling default when printing to paper. <PRINT_SCALING/>
//
//In order to force Acrobat to use "Actual Size" when printing,
//we need to set "PrintScaling" to "None".  As of PDF version 1.7 (Acrobat 8+),
//this setting is ignored unless it is associated with a "Enforce" setting.
//
//PDFSharp supports creating these "ViewerPreferences" settings.  When you pass it
//a setting string key (must be prefixed with a "/"), it creates a setting string with
//the key followed by the value within parentheses.  Such as:
//      /PrintScaling(None)
//
//However, with PDF 1.7, it must use the /Enforce setting.  By using Acrobat's
//document "Properties | Advanced" option, you can change the setting to find out that
//the correct format is:
//      /Enforce(PrintScaling)/PrintScaling/None
//
//Therefore, we will have PDFSharp create a string that is virtually identical
//to the one we need.  The "virtually identical" setting string will be:
//      /Enforce(PrintScaling/PrintScaling/None)
//Then, when all is done (save the doc stream to a byte array), we will replace
//the "virtually identical" setting string with a setting string that is what we want.
doc.Version = 17;
doc.ViewerPreferences.Elements.SetString("/Enforce", "PrintScaling/PrintScaling/None");

...generate PDF content...

//Convert doc to stream array
byte[] documentBytes;
using (MemoryStream stream = new MemoryStream())
{
   doc.Save(stream, false);
   stream.Seek(0, SeekOrigin.Begin);
   documentBytes= stream.ToArray();
}

//Make PDF to have a setting to force paper printing to use "Actual Size"
//as scaling default when printing to paper. <PRINT_SCALING/>
//
//We have /Enforce(PrintScaling/PrintScaling/None)
//We want /Enforce(PrintScaling)/PrintScaling/None
documentBytes= ReplaceBytes(documentBytes, GetASCIIBytes("PrintScaling/PrintScaling/None)"), GetASCIIBytes("PrintScaling)/PrintScaling/None"));


This relies on the following methods for replacing bytes in a byte array:
Code:
public static byte[] GetASCIIBytes(string str)
{
   byte[] bytes = System.Text.Encoding.ASCII.GetBytes(str);
   return bytes;
}

public static int FindBytes(byte[] src, byte[] find)
{
   int index = -1;
   int matchIndex = 0;
   // handle the complete source array
   for (int i = 0; i < src.Length; i++)
   {
      if (src[i] == find[matchIndex])
      {
         if (matchIndex == (find.Length - 1))
         {
            index = i - matchIndex;
            break;
         }
         matchIndex++;
      }
      else
      {
         matchIndex = 0;
      }

   }
   return index;
}

public static byte[] ReplaceBytes(byte[] src, byte[] search, byte[] repl)
{
   byte[] dst = null;
   int index = FindBytes(src, search);
   if (index >= 0)
   {
      dst = new byte[src.Length - search.Length + repl.Length];
      // before found array
      Buffer.BlockCopy(src, 0, dst, 0, index);
      // repl copy
      Buffer.BlockCopy(repl, 0, dst, index, repl.Length);
      // rest of src array
      Buffer.BlockCopy(
         src,
         index + search.Length,
         dst,
         index + repl.Length,
         src.Length - (index + search.Length));
   }
   else
   {
      dst = src;
   }

   return dst;
}


Hope this helps someone.
-Arizona

Page 1 of 1 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/