PDF specific features

XFRX 16.1

Member  oDocument of XFRX Session object is deprecated. You can use member oDocumentWriter.

XFRX 17.3

Member  oDocument of XFRX Session object is removed.

Appending generated output to existing PDF Documents

This paragraph applies both to VFP 9 and VFP 8.

From version 10.1, XFRX is able to append the generated report to an existing PDF document. It is possible to append the report at the end of the document or at an arbitrary position within the document: with either inserting the new pages or replacing the pages in the existing PDF document.

In XFRX for VFP 8 this feature is controlled by a new parameter of SetParams(…) method: tuAppend. Please see the SetParams method reference for more information about setting this parameter.

In XFRX for VFP 9 you can interchangeably use the new parameter of SetParams(…) method or AppendToFile property of the XFRXListener class.

Notes

  1. It's not guaranteed that XFRX will be able to append to any PDF document. It works fine with PDF documents generated by XFRX and we've successfully tested PDFs from other sources, too, but the PDF specification allows for some internal structures that XFRX wouldn't be able to decode. (To be precise: XFRX doesn’t support linearized PDF documents and documents that use page tree structures).
  2. Because of the way the PDF file is constructed, the size of the PDF document never shrinks, even if the number of pages in the resulting PDF document is smaller than in the original one.

Example: The TEST.FRX report will be appended to the existing TEST.PDF document. If the TEST.PDF file does not exist, it will be created.

LOCAL m.loXFRX, m.lnRetVal
m.loXFRX = XFRX("XFRX#LISTENER")
m.lnRetVal = m.loXFRX.SetParams("test.pdf",,,,,,"PDF",,,,.T.)
IF m.lnRetVal = 0
   REPORT FORM test OBJECT m.loXFRX
ENDIF

PDF Encryption

This paragraph applies both to VFP 9 and VFP 8. The setPasswords method is implemented both in XFRXListener and XFRXSession classes.

PDF documents can be encrypted. XFRX use RC4/AES algorithm only with key length 40-128 bits. The default key length is 40 bits for PDF version <=1.2 and 128 bits for later versions and it is possible to set the key length.

m.loSession.setOtherParams("KEYLENGTH", 10) && 80 bits

To set the encryption on, call setPasswords method:

m.loSession.setPasswords(m.tcOwnerPassword, m.tcUserPassword)
m.loSession.setPasswords("", "")                && no password
m.loSession.setPasswords("", m.tcUserPassword)  && user password only (open password) - owner password will be random.
m.loSession.setPasswords(m.tcOwnerPassword, "") && owner password only (edit password)

The user password can be empty. If the owner password is empty, a random string will be generated as the password.

Acrobat Reader doesn't support national characters in passwords: https://www.adobe.com/devnet-docs/acrobat/android/en/protect.html

Default method is V2 (RC4), but it's  possibly change to AES (128 bit) - since XFRX 21.1.

m.loSession.setOtherParams("CRYPMETHOD", "AESV2") && AES 128 bits

Append mode

Method setPasswords() must be calls before the SetParams() method for appending or replacing pages in an existing file.

The owner can do anything with the document. The user permissions can be set using the setPermission method:

m.loSession.setPermissions(m.tlPrintDocument, m.tlModifyDocument, ;
                           m.tlCopyTextAndGraphics, m.tlAddOrModifyAnnotations,;
                           m.tlFillFormFields, m.tlExtractTextAndGraphics, ;
                           m.tlAssembleDocument, m.tlPrintDocumentInLow)

The default values of the permissions is .F. (false). 

Parameters tlFillFormFields, tlExtractTextAndGraphics, tlAssembleDocument, tlPrintDocumentInLow are since XFRX 16.1.

PDF Font Embedding

This paragraph applies both to VFP 9 and VFP 8. The method is implemented both in XFRXListener and XFRXSession classes.

XFRX supports both whole font and font subset embedding.

OpenType font is include always.

To embed all characters of all used fonts, call:

m.loSession.setEmbeddingType(2)

before running the report.

To embed only the characters used, call:

m.loSession.setEmbeddingType(3)

Embedding only subset of fonts (characters used in the document) significantly reduces the size of the generated file.

To select which font to embed (e.g. when you need just to embed the barcode font, or font that is not installed on the pc the document will be sent to), add “#UR INCLUDEFONT” (without the quotation marks) to the comments of a field that uses the font (in the report). Add “#UR INCLUDEFONT SUBSET” comment to include the font subset.

Special code pages

XFRX set font embedding subset for special code pages (1250, 1251, 1257, 1254, 1253, 1255) and selected font (Arial, Arial CE, Arial Narrow, Arial Black, Courier New, Courier New CE, Times New Roman, Times New Roman CE) if detect national characters. XFRX set font embedding subset allways for Symbols or if you enable PDF/A support.

If you want change the default behavior (special code page) you can use parameter CHECKFONTFORSPECIALCODEPAGE (for disable or enable) or ADDFONTFORSPECIALCODEPAGE (for add font to list) - since XFRX 17.1

loSession.SetOtherParams("CHECKFONTFORSPECIALCODEPAGE",.F.) && Disable the behavior
loSession.SetOtherParams("ADDFONTFORSPECIALCODEPAGE","Tahoma") && Add font to list

Checking font's code page

As of version 19.0, XFRX check if font support selected codepage for text. If no, then XFRX change font name to "Arial". Many old True Type  fonts are old and supports only default code page for western (1252 for western Europe, USA etc.) These fonts can cause problem in central or eastern Europe. But it's prossible change default behavior and turn off checking font's codepage.

XFRX 22.3
loSession.SetOtherParams("DONTCHECKFONTCODEPAGE",.T.)

Barcode support (#UR SYMBOLFONT)

(Obsolete since XFRX 15.7) Put "#UR SYMBOLFONT" into the comment of the report field that contains the barcode. This will instruct the engine not to do any codepage conversions and flag the font as a symbol font in the PDF document.

Parameter UNICODE support

You can set UNICODE output for document.

To select which font to embed as UNICODE (e.g. when you need just to embed the barcode font, or font that is not installed on the pc the document will be sent to), add “#UR INCLUDEFONT UNICODE” (without the quotation marks) to the comments of a field that uses the font - in the report (since XFRX 16.0).

m.loSession.SetOtherParams("UNICODE",.T.) 

True type font in PDF support only 256 characters.  It causes problems to the version XFRX 18.2 for japanese and chinese text.

XFRX 19.0 use UCS2  for codepage 932, 936, 950 and UTF-8 as default option.


m.loSession.SetOtherParams("UCS2ALLOWED",.F.)  && disable using UCS2

Digital signatures in PDF

The digital signature can be used to validate the document content and the identity of the signer. (You can find more at http://en.wikipedia.org/wiki/Digital_signature). XFRX implements the "MDP (modification detection and prevention) signature" based on the PDF specification version 1.7, published in November 2006.

The signing algorithm in XFRX computes the encrypted document digest and places it, together with the user certificate, into the PDF document. When the PDF document is opened, the Adobe Acrobat (Reader) validates the digest to make sure the document has not been changed since it was signed. It also checks to see if the certificate is a trusted one and complains if it is not. The signature dictionary inside PDF can also contain additional information and user rights - see below.

At this moment XFRX supports invisible signatures only (Acrobat will show the signature information, but there is no visual element on the document itself linking to the digital signature). We will support visible signatures in future versions.

In the current version, XFRX is using the CMS/PKCS #7 detached messages signature algorithm in the .net framework to calculate the digest - which means the .NET framework 2.0 or newer is required. The actual process is run via an external exe - "xfrx.sign.net.exe", that is executed during the report conversion process. In future, we can alternatively use the OpenSSL library instead.

How to invoke the digital signing

The syntax is the same for VFP 9.0 and pre-VFP 9.0 calling methods

To generate a signed PDF document, call the DigitalSignature() method before calling SetParams. Please see the DigitalSignature() method reference for more information about setting this parameter.

Demo

The demo application that is bundled with the package (demo.scx/demo9.scx) contains a testing self-signed certificate file (TestEqeus.pfx) and a sample that creates a signed PDF using the pfx. Please note Acrobat will confirm the file has not changed since it was signed, but it will complaing the certificate is not trusted - you would either need to add the certificate as a trusted one or you would need to use a real certificate from a certification authority (such as VeriSign).

Empty signature field

Put #UR EMPTYSIGNATURE=expr  into the comment of the report shape for creating empty field for signature. Example: #UR EMPTYSIGNATURE="My Signature"

This feature is since XFRX 17.1

PDF/A support

PDF/A is an ISO standard for the digital preservation of electronic documents. PDF/A document is a PDF document with specific restrictions that ensure that the document will always display and print exactly the same way, no matter which platform or document viewer is used:

  • Platform independent
  • No hidden or transparent content (PDF/A-1x)
  • All information needed to display the document is embedded (including fonts)
  • Document metadata stored as XML
  • No encryption, no password protection
  • No javascript or other executable parts
  • No LZW compression
  • Displayed and printed content must match (all annotations must be printed)

There are currently two PDF/A specifications:

  • PDF/A-1 from 2005
  • PDF/A-2 from 2011
  • PDF/A-3 from 2014

XFRX currently supports specification:

PDFA levelsupport unsignedsigned
1ayesvalidvalid
1byesvalidvalid
2ayes  (XFRX 16.0)validnonvalid
2byes  (XFRX 16.0)validnonvalid
2uyes  (XFRX 16.0)validnonvalid
3ayes  (XFRX 16.0)validnonvalid
3byes  (XFRX 16.0) validnonvalid
3uyes  (XFRX 16.0) validnonvalid

Please note the PDF/A-enabled document files can be significantly larger than regular PDF documents because the used fonts must always be included.

Invoking PDF/A

To generate a PDF/A document, call SetPDFA(.T.,[lcLevel]) method on the session object before processing. This method is available in VFP8 and VFP9 session objects, as well as the XFRX#DRAW object.

Example:

LOCAL m.loXFRX, m.lnRetVal
m.loXFRX = EVALUATE([XFRX("XFRX#LISTENER")])
m.loXFRX.setpdfa(.T.) && 1b
*m.loXFRX.setpdfa(.T.,"1a") && 1a 
*m.loXFRX.setpdfa(.T.,"1b") && 1b 
*m.loXFRX.setpdfa(.T.,"2a") && 2a 
*m.loXFRX.setpdfa(.T.,"2b") && 2b
*m.loXFRX.setpdfa(.T.,"2u") && 2u
*m.loXFRX.setpdfa(.T.,"3a") && 3a
*m.loXFRX.setpdfa(.T.,"3b") && 3b
*m.loXFRX.setpdfa(.T.,"3u") && 3u     
m.lnRetVal = m.loXFRX.SetParams("pdfa9.pdf",,,1250,,,"PDF")
IF m.lnRetVal = 0
   REPORT FORM demoreps\invoices OBJECT m.loXFRX
ENDIF

CMYK support

Put #UR COLOR "CMYK"  into the comment of the report images in CMYK.

Since XFRX 18.1 this directive is obsolete.

Negative image support

Put #UR COLOR "NEG"  into the comment of the report images in negative colors.

MASK support - transparent image

Put #UR MASK "[255 255 255 255 255 255]" for images with transparent colors. See to "Color Key Masking" in pdf reference.

You can set general  color for images with transparent background (since XFRX 16.1)  Default color is white - RGB(255,255,255)

m.loSession.SetOtherParams("TRANSPARENTCOLOR",RGB(192,192,192)) 

MASK Image support - external mask image for creating transparent image

Put  #UR SMASKIMAGE=<expression> if you want create transparent or alpha effect. Mask image must be in grey scale (PNG, BMP) with 1 bpc, 2 bpc, 4 bpc, 8 bpc, 16 bpc. This directive is equal to /SMask operator.

Put  #UR MASKIMAGE=<expression> if you want create transparent . Mask image must be in grey scale (PNG, BMP) with 1 bpcThis directive is equal to /Mask operator.

Since XFRX 18.1. If output is PDF/A-1a or PDF/A-1b then XFRX ignore the directive.

#UR MASKIMAGE was renamed to #UR SMASKIMAGE since XFRX 19.0

Default picture format

(since XFRX 16.2.0)

PDF output knows only jpeg, bitmap and PNG pictures. Other  format pictures converts to bitmap (default choice). You can change to jpeg.

m.loSession.SetOtherParams("DEFAULTPICTUREFORMAT",'jpeg') 

CMYK to RGB

(since XFRX 18.1.0)

Because XFRX .18.1 (since) don't convert JPEG-CMYK to JEPG-RGB, is possibility turn off  the behavior.

m.loSession.SetOtherParams("CMYK2RGB",.T.)

Turn Off alpha chanel or transparent pixels

(since XFRX 18.1.0)

You can use parameter TRANSPARENTOFF for backware compatibility.

m.loSession.SetOtherParams("TRANSPARENTOFF",.T.)

Debug mode 

Parameter DONOTPUTDOCUMENTID

On french OS you can have problem with searching in Adobe Reader. In this case you can set parameter DONOPUTDOCUMENTID, if you do not use passwords or digital signature.

m.loSession.SetOtherParams("DONOTPUTDOCUMENTID,.T.) 

Parameters DEVELOP and DEVELOPFOLDER

If you set these parameters, xfrx copy temporary files into specified folder. 

m.loSession.setOtherParams("DEVELOP",.T.)
m.loSession.setOtherParams("DEVELOPFOLDER",lcPath+"_out\"+lcOut)

Parameter  DONOTZIPTEXTSTREAM

If you set the parameter, output stream inside PDF will not be compressed.  

m.loSession.SetOtherParams("DONOTZIPTEXTSTREAM",.T.)

Page layout, Page mode and Viewer Preferences

(since XFRX 16.0)

ParameterValueDescription
PageLayout

specifying the page layout to be used when the document is opened 


"SinglePage" Display one page at a time

"OneColumn" Display the pages in one column

"TwoColumnLeft" Display the pages in two columns, with odd-numbered pages on the left

"TwoColumnRight" Display the pages in two columns, with odd-numbered pages on the right

"TwoPageLeft"

 
Display the pages two at a time, with odd-numbered pages on the left

"TwoPageRight"

Display the pages two at a time, with odd-numbered pages on the right
  
PageModespecifying how the document should be displayed when opened

"UseNone"Neither document outline nor thumbnail images visible

"UseOutlines"Document outline visible

"UseThumbs"Thumbnail images visible

"FullScreen"Full-screen mode, with no menu bar, window controls, or any other window visible

"UseOC"Optional content group panel visible

"UseAttachments"Attachments panel visible
ParameterValuePDF Version Description
ViewerPreferencesHideToolbar.T.
A flag specifying whether to hide the viewer application’s tool bars when the document is active. Default value: .F..
ViewerPreferencesHideMenubar.T.
A flag specifying whether to hide the viewer application’s menu bar when the document is active. Default value: .F..
ViewerPreferencesHideWindowUI.T.
A flag specifying whether to hide user interface elements in the document’s window (such as scroll bars and navigation controls), leaving only the document’s contents displayed. Default value: .F..
ViewerPreferencesFitWindow.T.
A flag specifying whether to resize the document’s window to fit the size of the first displayed page. Default value: .F..
ViewerPreferencesCenterWindow.T.
A flag specifying whether to position the document’s window in the center of the screen. Default value: .F..
ViewerPreferencesDisplayDocTitle.T. 1.4A flag specifying whether the window’s title bar should display the document title taken from the Title entry of the document information dictionary (see Section 10.2.1, “Document Information Dictionary”). If false, the title bar should instead display the name of the PDF file containing the document. Default value: .F..
   
ViewerPreferencesNonFullScreenPageMode

The document’s page mode, specifying how to display the document on exiting full-screen mode.


"UseNone"
Neither document outline nor thumbnail images visible.


"UseOutlines"
Document outline visible.


"UseThumbs"
Thumbnail images visible.


"UseOC"
Optional content group panel visible.
   
ViewerPreferencesDirection
1.3The predominant reading order for text.


"L2R"
Left to right.


"R2L"
Right to left .
    
ViewerPreferences  PrintScaling
1.6The page scaling option to be selected when a print dialog is displayed for this document  


"None"
Indicates that the print dialog should reflect no page scaling.


"AppDefault"
Indicates that applications should use the current print scaling. 
    
ViewerPreferences  Duplex
1.7The paper handling option to use when printing the file from the print dialog. 


"Simplex"
Print single-sided.


"DuplexFlipShortEdge"
Duplex and flip on the short edge of the sheet .


"DuplexFlipLongEdge"
Duplex and flip on the long edge of the sheet. 
    
ViewerPreferences PickTrayByPDFSize.T.1.7A flag specifying whether the PDF page size is used to select the input paper tray 
ViewerPreferences PrintPageRange"0 1"1.7 The page numbers used to initialize the print dialog box when the file is printed. 
ViewerPreferences NumCopies 21.7 The number of copies to be printed when the print dialog is opened for this file 

  

LOCAL m.loSession, m.lnRetVal
m.loSession=EVALUATE([xfrx("XFRX#INIT")])
m.lnRetVal = m.loSession.SetParams("some.pdf",,,,,,"PDF")
IF m.lnRetVal = 0
   m.loSession.setOtherParams("PAGELAYOUT","SinglePage") && SinglePage, OneColumn, TwoColumnLeft, TwoColumnRight, TwoPageLeft, TwoPageRight
   m.loSession.setOtherParams("PAGEMODE","UseOutlines") && UseNone, UseOutlines, UseThumbs, FullScreen, UseOC, UseAttachments 
   m.loSession.setOtherParams("VIEWERPREFERENCES","HIDETOOLBAR",.F.) 
   m.loSession.setOtherParams("VIEWERPREFERENCES","HIDEMENUBAR",.F.) 
   m.loSession.setOtherParams("VIEWERPREFERENCES","HIDEWINDOWUI",.F.) 
   m.loSession.setOtherParams("VIEWERPREFERENCES","FITWINDOW",.F.) 
   m.loSession.setOtherParams("VIEWERPREFERENCES","CENTERWINDOW",.T.) 
   m.loSession.setOtherParams("VIEWERPREFERENCES","DISPLAYDOCTITLE",.T.) 
   m.loSession.setOtherParams("VIEWERPREFERENCES","NONFULLSCREENPAGEMODE","UseOC") && UseNone,UseOutlines,UseThumbs ,UseOC
   m.loSession.setOtherParams("VIEWERPREFERENCES","DIRECTION","L2R") && L2R,R2L
   m.loSession.setOtherParams("VIEWERPREFERENCES","PRINTSCALING","AppDefault") && AppDefault, None
   m.loSession.setOtherParams("VIEWERPREFERENCES","DUPLEX","Simplex") && Simplex, DuplexFlipShortEdge, DuplexFlipLongEdge
   m.loSession.setOtherParams("VIEWERPREFERENCES","PICKTRAYBYPDFSIZE",.T.) 
   m.loSession.setOtherParams("VIEWERPREFERENCES","PRINTPAGERANGE","0 0 1 1") && 0 1 (1-2)| 0 0 1 1 (1,2)
   m.loSession.setOtherParams("VIEWERPREFERENCES","NUMCOPIES",2)
ENDIF

 

PDF version 

(since XFRX 16.1)

You can set PDF version. Default version is 1.6 for XFRX 16.0, 1.7 for XFRX 16.1. Change PDF version must be first after calls setParams() method. 

m.loSession.setOtherParams("VERSION","1.5")

TAB size 

(since XFRX 17.0.0)

Specifies the width, in characters, of a tab. Default value is 4.

m.loSession.setOtherParams("TABSIZE",3)


Attachments

(since XFRX 17.3)

PDF 1.3 supports attachments. PDF/A-1 doesn't support attachments. PDF/A-2 does support attachments - only PDF file (PDF/A). PDF/A-3 does support attachments - any file.
For add atttchment calls method addAttachment.

Add attachment example - pdf

LOCAL m.loSession, m.lnRetVal 
m.loSession=EVALUATE([xfrx("XFRX#INIT")]) 
m.lnRetVal = m.loSession.SetParams("some.pdf",,,,,,"PDF")
IF m.lnRetVal = 0
   m.loSession.addAttachment("another.pdf",.T.,"","application/pdf","Alternative")
   m.loSession.addAttachment("second.xls",.T.,"","application/xls","Alternative")

   m.loSession.ProcessReport("report.frx") 
ENDIF

Add attachment example - ZUGFeRD xml

(http://www.ferd-net.de/)

LOCAL m.loSession, m.lnRetVal 
m.loSession=EVALUATE([xfrx("XFRX#INIT")]) 
m.lnRetVal = m.loSession.SetParams("some.pdf",,,,,,"PDF")
m.loSession.setpdfa(.T., "3B")
IF m.lnRetVal = 0
   * Relation type must be "Alternative"
   m.loFile=loSession.addAttachment("ZUGFeRD-invoice.xml",.T.,"Rechnungsdaten im ZUGFeRD-XML-Format","text/xml","Alternative")
   m.loFile.CreateZUGFeRDMetadata("BASIC","INVOICE","1.0") && if you use PDFA

   m.loSession.ProcessReport("report.frx") 
ENDIF

Add attachment example - FacturX xml

(http://fnfe-mpe.org/)

Method CreateFACTURXMetadata() was added in XFRX 19.0


LOCAL m.loSession, m.lnRetVal 
m.loSession=EVALUATE([xfrx("XFRX#INIT")]) 
m.lnRetVal = m.loSession.SetParams("some.pdf",,,,,,"PDF")
m.loSession.setpdfa(.T., "3B")
IF m.lnRetVal = 0
   * Relation type can be "Alternative" 
   m.loFile=loSession.addAttachment("FacturX-invoice.xml",.T.,"Données de facturation FacturX XML-Format","text/xml","Alternative")
   m.loFile.CreateFACTURXMetadata("BASIC","INVOICE","1.0") && if you use PDFA

   m.loSession.ProcessReport("report.frx") 
ENDIF

Add attachment example - ISDOC xml

 (http://www.isdoc.org/index.php?l=2)

LOCAL m.loSession, m.lnRetVal 
m.loSession=EVALUATE([xfrx("XFRX#INIT")]) 
m.lnRetVal = loSession.SetParams("some.pdf",,,,,,"PDF")
m.loSession.setpdfa(.T., "3B")
IF m.lnRetVal = 0
   loFile=loSession.addAttachment("Faktura.isdoc",.T.,"ISDOC - formát elektronické fakturace","text/xml","Alternative")
   loFile.CreateISDOCMetadata("INVOICE","5.2") && if you use PDFA

   m.loSession.ProcessReport("report.frx") 
ENDIF

Compression and memory level 

(since XFRX 22.0)

Specifies compression level (1-9)  and memory level (1-9) for deflate. 

If you specify compression level to -1 (default value), then compression level will be 6.

If you specify memory level to -1 (default value), then memory level will be 8.

If you specify compression level to 9 and memory level to 9, then data after deflate  will be smaller but it will take longer.


Compression level
m.loSession.setOtherParams("COMPRESSIONLEVEL", -1)


Memory level
m.loSession.setOtherParams("MEMORYLEVEL", -1)

MEMORYLEVEL was added in XFRX 23.0