EDDiMark Documentation

More about EDDiMark PDF

EDDiMark does its magic using the open-source TCPDF and TCPDI libraries (not developed or maintained by EDDiMark dev). TCPDI parses the existing PDF (assuming it is unencrypted and uncorrupted), recreating it in memory, and TCPDF applies your watermark. Regretfully, TCPDI is unable to parse certain PDF elements into memory, such as internal links and forms. However, hopefully this feature will be more stable in a future TCPDI release. Understanding a little about how TCPDI and TCPDF come into play, using PHP memory, might help you to create the most effective and efficient watermarks.

View the EDDiMark PDF changelog here.


PHP Version

You should be running at least PHP version 5.6 for all features of EDDiMark PDF to work, but higher that for it to work WELL. Wordpress recommends you run PHP version 7.2 or higher. EddiMark is PHP version 7.3 compatible, so don’t hesitate to upgrade after making backups. PHP 7.0 is twice as fast for Wordpress as PHP 5.6, and processes EDDiMark demands much more efficiently! This is the first thing you should try if you’re running out of memory while processing PDFs.

Increase Memory

Increase your PHP memory allotment to at least 64MB. We recommend a 128MB, 256MB or maybe even 512MB setting. If your host does not allow more than 16 or 32, it might be a good time to switch hosts or servers. If you expect your PDF to take more than 30 seconds to parse (gasp!), you may also need to increase your PHP max_execution_time.

Large PDFs?

If you are having trouble sharing large PDF files, keep in mind that your hosting plan needs to be robust enough to support the memory and bandwidth necessary to fulfill these requests. Try these suggestions: https://tcpdf.org/docs/performances/. (FYI Thai characters are already disabled in EDDiMark.) Keep your watermarks simple (avoid HTML if possible) and use non-Unicode fonts if possible (Helvetica, Times, Courier).

Maybe it’s time for a server upgrade?


EDDiMark comes with default margins to keep your watermark inside an area on the page. These are 10mm left/right, and 10mm top/bottom.

If you would like to remove this restriction, set the margins to 0. If you would like to move things in on the page, set the margins higher.

The XY fine tuners accomplish the same thing; however, they cannot remove the margins. So a margins setting was added primarily for those people wanting to remove the margins.

Simple Shortcodes

Simple shortcodes available are [FIRSTNAME] [LASTNAME] [EMAIL] [DATE] [PAYMENTID]. Using one of these in your overlay or footer text will cause the shortcode to be replaced by the customer data during watermarking.

[DATE] Shortcodes

[DATE] can be used as-is, and will insert the order date.

Future [DATE] Shortcodes

To add a future date marked from the date of purchase, you can use the [DATE-#YRS] [DATE-#MOS] [DATE-#WKS] [DATE-#DAYS] shortcode, where # is replaced with the number of days/months/weeks/years desired. This shortcode is based on 30-day months, and 365-day years, so it might be best to use days if you need precision.


[DATE-365DAYS] would be 365 days from the checkout date.

[DATE-2YRS] would be 730 days from the checkout date, but does not take into account a leap year.

Opacity Shortcodes

The {OPAC} shortcode — and watermarking with opacity — is totally unique to this plugin is very helpful for people not wanting to obscure their PDF content, since the watermark sits on top. It doesn’t always play nice with HTML in your watermark, so sometimes some rearranging will need to be done. Consider wrapping your HTML inside {OPAC} tags if trying to get opacity, if the inverse isn’t working.


{OPAC-0.5}This is sample text{/OPAC}

This is sample text” will be at 50% transparency. The tag needs a dash, then a number representing the fraction of 100% opacity.

{OPAC-0.1}This is very transparent text{/OPAC}

This is very transparent text” will be at 10% transparency.

Note there is an open tag and a close tag around the text. If text does not wrap when using this tag, you may have to use HTML <br> tags. {OPAC} tag is still beta.

Text alignment

To style a link <a> or tag when using HTML, the following inline CSS options are available: font-style:italic, font-weight:bold, and text-align:center and text-align:right. This feature allows you to center text – yay!

Here’s an example of the code used to center some text.

<span style="text-align: center; font-weight: bold;">center some bold text</span>

This might also work:

<span style="text-align: center"><strong>center some bold text</strong></span>

Hooks (actions/filters)

Hooks were included to make it possible to adjust EDDiMark to carry out some of your specific needs. The hooks are NOT supported by EDDiMark staff unless you find a bug or need arguments added. We will not be able to write actions and filter code for you. The hooks were placed for your developer’s convenience.

‘ eddimark_add_custom_font ‘ and ‘ eddimark_font_decode ‘, and ‘ eddimark_out_charset ‘ filters, more here

‘ eddimark_add_barcode ‘ filter for maybe adding barcodes

‘ eddimark_settings_array ‘ filter to allow for manipulation of main watermarking settings (possibly to add settings).

‘ eddimark_set_zoom_mode ‘ and ‘ eddimark_set_viewer_preferences ‘ filters for setting PDF viewing preferences via TCPDF. Examples of SetDisplayMode() in use. More on TCPDF setViewerPreferences() here.

‘ eddimark_use_uploads_dir ‘ filter to use wp-content/uploads/eddimark-pdf/ folder to retain copies of watermarked files. This might only be desired if using the filter, ‘ eddimark_file_name ‘, where a distinct file name is created per order/customer. Otherwise the file is kept in the system /tmp folder, and automatically wiped.

Want to keep a copy of watermarked files? Use the ‘ eddimark_dont_cleanup ‘ filter hook, with something like the following code in your theme or in a plugin:

add_filter( 'eddimark_dont_cleanup', '__return_true' );
add_filter( 'eddimark_use_uploads_dir', '__return_true' );

IMPORTANT NOTE: If you keep files, your file names must be distinct. EDDiMark takes care of this for you by adding a timestamp to the PDF file name. You can filter this with the ‘ eddimark_file_name ‘ hook.

Considering keeping your files and need to rename them something more custom? The following code replaces the timestamp with the EDD order key:

add_filter( 'eddimark_file_name', 'eddimark_alter_file_name', 10, 2 );
eddimark_alter_file_name( $file_name, $key ) {

    // replaces the timestamp in the filename with the unique download key
    $file_name = preg_replace( '/_([0-9]{10})\.pdf/', '', $file_name ) . '_' . $key . '.pdf';
    return $new_file_path;


Fonts (maybe adding)

To run watermarking with your custom font, you can run the filter “eddimark_add_custom_font”. Font must be added to TCPDF first using AddFont(). Please read TCPDF docs. Fonts which come with TCPDF can also be added back in to the fonts folder; they were removed to keep this plugin as lightweight as possible. This is in development and not a supported feature.

add_filter( 'eddimark_add_custom_font', ‘eddimark_custom_font_name’, 10, 1 );
function eddimark_custom_font_name() {
    $font = TCPDF_FONTS::addTTFfont( $font_file, $font_type, $enc, $flags, $outpath, $platid, $encid, $addcbbox, $linkbox );
    return $font;

Keep in mind the $font value you return will be run in SetFont() while EDDiMark does its magic.

addTTFfont() parameters:

$fontfile (string) Font file (full path).
$fonttype (string) Font type. Leave empty for autodetect mode. Valid values are: TrueTypeUnicode, TrueType, Type1, CID0JP = CID-0 Japanese, CID0KR = CID-0 Korean, CID0CS = CID-0 Chinese Simplified, CID0CT = CID-0 Chinese Traditional.
$enc (string) Name of the encoding table to use. Leave empty for default mode. Omit this parameter for TrueType Unicode and symbolic fonts like Symbol or ZapfDingBats.
$flags (int) Unsigned 32-bit integer containing flags specifying various characteristics of the font (PDF32000:2008 – 9.8.2 Font Descriptor Flags): +1 for fixed font; +4 for symbol or +32 for non-symbol; +64 for italic. Fixed and Italic mode are generally autodetected so you have to set it to 32 = non-symbolic font (default) or 4 = symbolic font.
$outpath (string) Output path for generated font files (must be writeable by the web server). Leave empty for default font folder.
$platid (int) Platform ID for CMAP table to extract (when building a Unicode font for Windows this value should be 3, for Macintosh should be 1).
$encid (int) Encoding ID for CMAP table to extract (when building a Unicode font for Windows this value should be 1, for Macintosh should be 0). When Platform ID is 3, legal values for Encoding ID are: 0=Symbol, 1=Unicode, 2=ShiftJIS, 3=PRC, 4=Big5, 5=Wansung, 6=Johab, 7=Reserved, 8=Reserved, 9=Reserved, 10=UCS-4.
$addcbbox (boolean) If true includes the character bounding box information on the php font file.
$link (boolean) If true link to system font instead of copying the font data (not transportable) – Note: do not work with Type1 fonts.

If your overlay or footer are not looking right after you’ve added a new font, the filter ‘wwpdf_font_decode’ might need to be used to add html_entity_decode() around your overlay or footer input.

Passwords & Encryption

Be aware that protecting a PDF requires to encrypt it, which increases the processing time a lot. This can cause a PHP time-out in some cases, especially if the document contains images or fonts.

The file will be automatically encrypted if a password is set. If you don’t set any password, the document will open as usual. If you set a user password, the PDF viewer will ask for it before displaying the document (learn more about implications here). Typing the word “email” into the password field in EDDiMark settings will force the end user to open the PDF with the buyer’s email address.

The permission array is composed of values taken from the following ones (specify the ones you want to block):

  • The following are set together:
    • print : Print the document
    • print‑high : Print the document to a representation from which a faithful digital copy of the PDF content could be generated. When this is not set, printing is limited to a low-level representation of the appearance, possibly of degraded quality.
  • The following are set together:
    • modify : Modify the contents of the document by operations other than those controlled by ‘fill-forms’, ‘extract’ and ‘assemble’
    • assemble : Assemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even if ‘modify’ is not set
  • copy : Copy or otherwise extract text and graphics from the document
  • The following are set together:
    • annot‑forms : Add or modify text annotations, fill in interactive form fields, and, if ‘modify’ is also set, create or modify interactive form fields (including signature fields)
    • Fill‑forms : Fill in existing interactive form fields (including signature fields), even if ‘annot-forms’ is not specified

More information about SetProtection() here.

Recommended you allow:
  • Copy. If not allowed this document will not be readable by humans who rely on screen readers instead of their eyes to read. Keep it accessible!

Barcodes (maybe adding)

To add a barcode somewhere on your page, you can use the ‘wwpdf_add_barcode’ filter. An example goes like this:

add_filter( 'eddimark_add_barcode', 'eddimark_barcode_function', 10, 1 );
function eddimark_barcode_function( $barcode_array ) {
    return array( '2D', 'Test Barcode', 'QRCODE', 100, 230, 30, 30 );

The ‘my_barcode_function’ function returns an array used by EDDiMark to create a barcode.

  1. The first argument accepts either ‘1D’ or ‘2D’.
  2. The second argument will be your barcode contents.
  3. The third argument states the TYPE of barcode (please refer to TCPDF documentation for 1D vs 2D barcode setup and appropriate names for barcode types.)
  4. The fourth argument is X-axis placement. In the example, I have it set 10cm (100mm) over to the right.
  5. The fifth argument is Y-axis placement. In the example, I have it set 23cm (230mm) over to the right.
  6. The sixth argument is the width of the barcode in millimeters.
  7. The seventh argument is height of the barcode in millimeters.