#1 2014-07-24 01:05:50

MChaos
Member
Registered: 2014-07-23
Posts: 4

Enforce default print scaling

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!

Last edited by MChaos (2014-07-24 01:16:12)

Offline

#2 2014-07-28 17:05:11

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Enforce default print scaling

We have just added vpEnforcePrintScaling to TPdfViewerPreferences set - forcing PDF 1.6 file format to be explicit.
See http://synopse.info/fossil/info/7d49069f497

Does it sounds right to you?

Offline

#3 2014-08-04 22:18:30

MChaos
Member
Registered: 2014-07-23
Posts: 4

Re: Enforce default print scaling

That's great! Thank you!

Offline

#4 2014-08-05 00:30:06

MChaos
Member
Registered: 2014-07-23
Posts: 4

Re: Enforce default print scaling

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))

Offline

#5 2014-08-06 09:28:53

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Enforce default print scaling

Should be fixed by http://synopse.info/fossil/info/65e362e8f

I added your pseudo to the unit's credits BTW.
smile

Offline

#6 2014-08-13 16:51:00

MChaos
Member
Registered: 2014-07-23
Posts: 4

Re: Enforce default print scaling

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!

Last edited by MChaos (2014-08-13 18:16:30)

Offline

#7 2014-08-13 18:35:26

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Enforce default print scaling

Oups... I was too quick and optimistic this time...
Perhaps too much sun here in the French Riviera.
cool

Should be fixed by http://synopse.info/fossil/info/8aa9209b3c7

Thanks for the input!

Offline

Board footer

Powered by FluxBB