You are not logged in.
Pages: 1
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:
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
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
That's great! Thank you!
Offline
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
Should be fixed by http://synopse.info/fossil/info/65e362e8f
I added your pseudo to the unit's credits BTW.
Offline
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
Oups... I was too quick and optimistic this time...
Perhaps too much sun here in the French Riviera.
Should be fixed by http://synopse.info/fossil/info/8aa9209b3c7
Thanks for the input!
Offline
Pages: 1