#1 Re: PDF Engine » Enforce default print scaling » 2014-08-13 16:51:00

Thanks, ab!

But I should explain myself better: previous entries are 'boolean' and PrintScaling is of 'name' type. This way, if only line 7225 is changed, remaining entries will not be added correctly.

I mean,

vpHideToolbar, vpHideMenubar, vpHideWindowUI, vpFitWindow, vpCenterWindow
are all boolean entries and should be added with
TPdfBoolean.Create(true)

vpEnforcePrintScaling
is a name entry and should be added with
TPdfName.Create('None')

I guess a quick fix checking the condition will do it:

procedure TPdfCatalog.SetViewerPreference(Value: TPdfViewerPreferences);
var V: TPdfViewerPreference;
    FDictionary: TPdfDictionary;
begin
  FDictionary := FData.PdfDictionaryByName('ViewerPreferences');
  if (FDictionary=nil) and (Value<>[]) then begin
    FDictionary := TPdfDictionary.Create(Data.ObjectMgr);
    FData.AddItem('ViewerPreferences', FDictionary);
  end;
  if FDictionary<>nil then begin
    for V := low(V) to high(V) do
      if V in Value then
        if V = vpEnforcePrintScaling then
          FDictionary.AddItem(PDF_PAGE_VIEWER_NAMES[V], TPdfName.Create('None')) else
          FDictionary.AddItem(PDF_PAGE_VIEWER_NAMES[V], TPdfBoolean.Create(true)) 
      else
        FDictionary.RemoveItem(PDF_PAGE_VIEWER_NAMES[V]);
    if vpEnforcePrintScaling in Value then begin
      FDictionary.AddItem('Enforce', TPdfArray.CreateNames(Data.ObjectMgr,['PrintScaling']));
      if fOwner<>nil then
        fOwner.fFileFormat := pdf16;
    end else
      FDictionary.RemoveItem('Enforce');
  end;
end;

Alternatively, PrintScaling (and enforcing it or not) could be set like NonFullScreenPageMode.

There are another 10 options but dealing with them all would require other modifications.

Thank you again!

#2 Re: PDF Engine » Enforce default print scaling » 2014-08-05 00:30:06

Oh, there is a problem...

PrintScaling is an entry of type 'name' and not 'boolean' as those in TPdfViewerPreference. Possible values are None and AppDefault.

This way, I guess it should be added with

TPdfDictionary.AddItem('PrintScaling', TPdfName.Create('None'))

instead of (line 7225)

TPdfDictionary.AddItem('PrintScaling', TPdfBoolean.Create(true))

#4 PDF Engine » Enforce default print scaling » 2014-07-24 01:05:50

MChaos
Replies: 6

Hello,

I am new to SynPdf and surprised with this brilliant work! Congratulations!

I need to produce PDF drawings that must keep exact dimensions when printed. Acrobat (and possibly other PDF viewers) has the "Fit to Page" as default print option and our users are rarely aware of this.

I've found in PDF Reference the PrintScaling (PDF 1.6) and, even better, the newer Enforce entries for the viewer preferences dictionary. We are not alone:

Adobe Supplement to the ISO 32000 ExtensionLevel 3 (June 2008) wrote:

Enforced viewer preferences
(...) In one application of this feature, consider a PDF document that contains architectural or engineering drawings. If the scaling of such a document were changed for printing, the document may be compromised. This feature can be used to enforce default print scaling, which ensures that the document is printed with the default scaling.

SynPDF provides only five of the ViewerPreferences options, excluding PrintScaling and Enforce. This way, I set them with the following code and good results with Acrobat 10:

uses SynPdf;

procedure TForm1.Button1Click(Sender: TObject);
var
  lPdf: TPdfDocumentGDI;
  lPage: TPdfPage;
  FDictionary: TPdfDictionary;

begin
  lPdf := TPdfDocumentGDI.Create;
  try
    // get or create dictionary
    FDictionary := lPdf.Root.Data.PdfDictionaryByName('ViewerPreferences');
    if (FDictionary=nil) then
    begin
      FDictionary := TPdfDictionary.Create(lPdf.Root.Data.ObjectMgr);
      lPdf.Root.Data.AddItem('ViewerPreferences', FDictionary);
    end;

    // create PrintScaling key and set its name value to None
    FDictionary.AddItem('PrintScaling', TPdfName.Create('None'));

    // enforce above "suggestion"
    // create Enforce key and set PrintScaling in its array
    FDictionary.AddItem('Enforce', TPdfArray.CreateNames(lPdf.Root.Data.ObjectMgr,['PrintScaling']));

    lPdf.ScreenLogPixels:= 254;

    lPage := lPdf.AddPage;
    lPdf.VCLCanvas.Pen.Style:= psSolid;
    lPdf.VCLCanvas.Pen.Width:= 1;
    lPdf.VCLCanvas.Pen.Color:= clBlack;

    // 100mm square
    lPdf.VCLCanvas.Rectangle(500, 500, 1500, 1500);

    lPdf.SaveToFile('C:\Syntest.pdf');
  finally
    lPdf.Free;
  end;
end;

Of course, I don't want to touch the original code, but I wonder if something like this could be considered for those with same requirements:

procedure TPdfCatalog.EnforceNoPrintScaling;
var FDictionary: TPdfDictionary;
begin
  FDictionary := FData.PdfDictionaryByName('ViewerPreferences');
  if FDictionary=nil then begin
    FDictionary := TPdfDictionary.Create(Data.ObjectMgr);
    FData.AddItem('ViewerPreferences', FDictionary);
  end;
  // create PrintScaling key and set its name value to None
  FDictionary.AddItem('PrintScaling', TPdfName.Create('None'));
  // enforce above "suggestion"
  // create Enforce key and set PrintScaling in its array
  FDictionary.AddItem('Enforce', TPdfArray.CreateNames(Data.ObjectMgr,['PrintScaling']));
end;

Finally, my Acrobat X honors the options, but it is a PDF 1.3 document with PDF 1.6+ settings. Does anybody know if that can lead to any issues?

Thanks!

Board footer

Powered by FluxBB