# PD4ML v3 to v4 Migration Guide

PD4ML v4 is a substantial rewrite of the engine underneath a largely familiar API surface. Most call sites carry over with only a renamed method or a changed parameter type, but a handful of areas -- most notably the conversion flow itself, and the classes used for page geometry -- changed enough in shape that a mechanical find-and-replace won't get an existing v3 integration all the way to a working v4 build. This guide walks through what changed and why, section by section, and closes with a full method-by-method correspondence table for the rest. It complements the [PD4ML Programmer's Manual](https://app.gitbook.com/s/33dI66uC6sTAcaPjppX2/) (written against v4 throughout) and the [Usage Examples](https://app.gitbook.com/s/33dI66uC6sTAcaPjppX2/usage-examples) page (which shows v3 and v4 code side by side for the majority of common tasks).

## 1. Activation

Software activation is new in v4. Where v3 shipped without any license-file mechanism, v4 looks for a `pd4ml.lic` file -- containing an activation code obtained from the vendor's licensing page -- on the classpath or in the working directory, unless a code or a license-file URL is passed explicitly to the `PD4ML` constructor instead. The activation code encodes both the licensed feature set and the maintenance/upgrade window it's valid for. Until a valid license is installed, PD4ML runs in evaluation mode: fully functional, but with watermarked output. If activation isn't taking effect as expected, `pd4ml.setLogLevel(255)` produces verbose diagnostic output that typically pinpoints why (an expired maintenance window, a code that doesn't match the running version, a `pd4ml.lic` that isn't actually on the classpath, and so on).

Existing license codes and account details are managed from the [View My Licenses](https://pd4ml.com/view-my-licenses/) page.

## 2. New Conversion Flow

The single biggest structural change is that conversion is no longer one call. v3's `render(source, output)` parsed the source and produced output in a single step, called once per output artifact. v4 splits this into an explicit two-phase model: `readHTML(...)` parses the source exactly once, after which any number of `writePDF(...)`, `writeRTF(...)`, `writeDOCX(...)`, or `renderAsImages(...)` calls can serialize that same parsed document to different formats or destinations -- without re-parsing. This also means metadata about the parsed document (via `getLastRenderInfo(...)`) becomes available for inspection before -- or instead of -- writing any output at all.

{% tabs %}
{% tab title="PD4ML v4" %}
```java
PD4ML pd4ml = new PD4ML();
String html = "TEST<pd4ml:page.break><b>Hello, World!</b>";
ByteArrayInputStream bais = new ByteArrayInputStream(html.getBytes());

// phase 1: parse
pd4ml.readHTML(bais);

File pdf = File.createTempFile("result", ".pdf");
FileOutputStream fos = new FileOutputStream(pdf);

// phase 2: render -- can be called more than once, against different
// write*()/renderAsImages() methods, without re-parsing
pd4ml.writePDF(fos);
```
{% endtab %}

{% tab title="PD4ML v3" %}
```java
PD4ML pd4ml = new PD4ML();
String html = "TEST<b>Hello, World!</b>";
StringReader bais = new StringReader(html);

File pdf = File.createTempFile("result", ".pdf");
FileOutputStream fos = new FileOutputStream(pdf);

// a single call both parses the source and writes the output
pd4ml.render(bais, fos);
```
{% endtab %}
{% endtabs %}

## 3. PDF Document Defaults: Scale Factor, Margins, and View Mode

Three settings govern how source content maps onto the printed page, and their defaults changed between versions: `pageSize` defaults to A4 in both, `pageMargins` defaults to 10 mm on every side in v4 versus the more granular 50/25/25/25 pt (top/right/bottom/left) in v3, and `htmlWidth` (the virtual viewport width the source is laid out against before scaling) defaults to 640px in both. An `htmlWidth` of 727px is worth knowing about specifically: at that value, and only that value, PD4ML's internal scale factor works out to a 1:1 pixel-to-point correspondence at the PDF-standard 72 DPI -- convenient when reasoning about how a CSS pixel dimension will translate to printed size.

An integration that needs to reproduce v3's original defaults exactly under v4, rather than adopt the new ones, can do so explicitly:

```java
PD4ML pd4ml = new PD4ML();
pd4ml.setParam(Constants.PD4ML_DOCUMENT_VIEW_MODE, "OneColumn");
pd4ml.setHtmlWidth(640);
pd4ml.addStyle("BODY { margin: 8px }", true);
pd4ml.setPageSize(PageSize.A4);
pd4ml.setPageMargins(new PageMargins(50, 25, 25, 25, Units.PT));
```

## 4. Document Headers and Footers

v3 modeled a header or footer as a `PD4PageMark` object, whose `getHtmlTemplate(int pageNumber)` method was invoked once per page to compute that page's markup. v4 replaces this with a direct HTML string passed to `setPageHeader()`/`setPageFooter()`, with an optional scope parameter targeting a specific page range in place of per-page conditional logic in code -- and the same content can equally well be declared inline in the source HTML with the `<pd4ml:page.header>`/`<pd4ml:page.footer>` tags. All three forms support the `$[page]`, `$[total]`, and `$[title]` placeholders.

{% tabs %}
{% tab title="PD4ML v4 (API)" %}
```java
pd4ml.setPageHeader("$[title]", 30, "1");
pd4ml.setPageFooter("Total pages: $[total]", 30, "1");

pd4ml.setPageHeader("<b>$[title]</b> $[page]/$[total]", 30, "2+");
pd4ml.setPageFooter("<div style='width: 100%; text-align: right'>Page: $[page]</div>", 30, "2+");
```
{% endtab %}

{% tab title="PD4ML v4 (inline tags)" %}
```html
<html>
<head>
<title>Header/Footer example</title>
<style>BODY {font-family: Arial}</style>
</head>
<body>

<pd4ml:page.header height=30>$[title]</pd4ml:page.header>
<pd4ml:page.footer height=30>Total pages: $[total]</pd4ml:page.footer>

First Page

<pd4ml:page.break>

<pd4ml:page.header height=30><b>$[title]</b> $[page]/$[total]</pd4ml:page.header>
<pd4ml:page.footer height=30><div style='width: 100%; text-align: right'>Page: $[page]</div></pd4ml:page.footer>

Second Page
</body>
</html>
```
{% endtab %}

{% tab title="PD4ML v3" %}
```java
PD4PageMark header = new PD4PageMark() {
    public String getHtmlTemplate(int pageNumber) {
        if (pageNumber == 1) {
            return "<html><body>$[title]";
        } else {
            return "<html><body><b>$[title]</b> $[page]/$[total]";
        }
    }
};
PD4PageMark footer = new PD4PageMark() {
    public String getHtmlTemplate(int pageNumber) {
        if (pageNumber == 1) {
            return "<html><body>Total pages: $[total]";
        } else {
            return "<html><body><div style='width: 100%; text-align: right'>Page: $[page]</div>";
        }
    }
};
header.setAreaHeight(30);
footer.setAreaHeight(30);

pd4ml.setPageHeader(header);
pd4ml.setPageFooter(footer);
```
{% endtab %}
{% endtabs %}

See also the [Programmer's Manual's JSP taglib section](https://pd4ml.com/support-topics/pd4ml-v4-programmers-manual/#pd4ml-jsp-taglib-and-web-applications) for the same placeholders used from a JSP page.

## 5. JSP Taglib

The JSP taglib now ships as an integral part of the main library rather than a separate artifact. The recommended custom-tag prefix also changed, from `pd4ml:` to `pd4tl:` -- freeing `pd4ml:` to unambiguously refer only to PD4ML's own proprietary tags (`<pd4ml:page.break>` and the like) within the same page, rather than being shared between the taglib's own directives and PD4ML's markup extensions.

```jsp
<%@ taglib uri="https://pd4ml.com/tlds/4.0" prefix="pd4tl"%>
<%@page contentType="text/html; charset=ISO8859_1"%>
<pd4tl:transform
  screenWidth="400"
  pageFormat="A5"
  pageOrientation="landscape"
  pageInsets="100,100,100,100,points">
<html>
<head>
<title>pd4ml test</title>
<style type="text/css">
body {
	color: red;
	font-family: Tahoma, "Sans-Serif";
	font-size: 10pt;
}
</style>
</head>
<body>
	<p>Hello, World!</p>
	<pd4ml:page.break />
	<table style="border: 1px solid gray; border-radius: 5px; background-color: #f8f8f8; color: #000000">
		<tr>
			<td>Hello, New Page!</td>
		</tr>
	</table>
</body>
</html>
</pd4tl:transform>
```

## 6. Full API Correspondence Table

The table below maps every v3 `PD4ML` method referenced in the vendor's migration notes to its v4 successor, linking each to its respective Javadoc (v3's now-archived Javadoc at `old.pd4ml.com`, and v4's current one). Where a v3 method has no listed v4 successor, that most often means its functionality was folded into a more general mechanism described elsewhere in this guide, or the behavior it controlled is now automatic; treat those as "no longer applicable" rather than "still there under a different name."

| v3 method                                                                                                                                                                                                                                                                               | v4 method                                                                                                                                                                                                                                                                                                                                                                                                                                      | What changed                                                                                                                                                                                                                                                                                |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`addDocumentActionHandler(String, String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#addDocumentActionHandler\(java.lang.String,%20java.lang.String\))                                                                                                                     | [`addDocumentActionHandler(String, String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#addDocumentActionHandler-java.lang.String-java.lang.String-)                                                                                                                                                                                                                                                                                       | Unchanged                                                                                                                                                                                                                                                                                   |
| [`addMetadata(String, String, boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#addMetadata\(java.lang.String,%20java.lang.String,%20boolean\))                                                                                                                           | [`addMetadata(String, String, boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#addMetadata-java.lang.String-java.lang.String-boolean-)                                                                                                                                                                                                                                                                                                | Unchanged                                                                                                                                                                                                                                                                                   |
| [`addStyle(String, boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#addStyle\(java.lang.String,%20boolean\))                                                                                                                                                             | [`addStyle(String, boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#addStyle-java.lang.String-boolean-)                                                                                                                                                                                                                                                                                                                               | Unchanged                                                                                                                                                                                                                                                                                   |
| [`addStyle(URL, boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#addStyle\(URL,%20boolean\))                                                                                                                                                                             | [`addStyle(URL, boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#addStyle-java.net.URL-boolean-)                                                                                                                                                                                                                                                                                                                                      | Unchanged                                                                                                                                                                                                                                                                                   |
| [`adjustHtmlWidth()`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#adjustHtmlWidth\(\))                                                                                                                                                                                         | [`adjustHtmlWidth(boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#adjustHtmlWidth-boolean-)                                                                                                                                                                                                                                                                                                                                          | Now takes an explicit boolean instead of being an always-on toggle call                                                                                                                                                                                                                     |
| [`changePageOrientation(Dimension)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#changePageOrientation\(Dimension\))                                                                                                                                                           | [`PageSize.rotate()`](https://pd4ml.com/javadoc/com/pd4ml/PageSize.html#rotate--)                                                                                                                                                                                                                                                                                                                                                              | Moved from a `PD4ML` instance method to a method on `PageSize` itself                                                                                                                                                                                                                       |
| [`clearCache()`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#clearCache\(\))                                                                                                                                                                                                   | [`terminate()`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#terminate--)                                                                                                                                                                                                                                                                                                                                                                    | Renamed                                                                                                                                                                                                                                                                                     |
| [`disableHyperlinks()`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#disableHyperlinks\(\))                                                                                                                                                                                     | [`enableHyperlinks(boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#enableHyperlinks-boolean-)                                                                                                                                                                                                                                                                                                                                        | Inverted: call `enableHyperlinks(false)`                                                                                                                                                                                                                                                    |
| [`enableDebugInfo()`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#enableDebugInfo\(\))                                                                                                                                                                                         | [`setLogLevel(int)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setLogLevel-int-)                                                                                                                                                                                                                                                                                                                                                          | Replaced by a graduated log level; use `setLogLevel(255)` for maximum verbosity                                                                                                                                                                                                             |
| [`enableImgSplit(boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#enableImgSplit\(boolean\))                                                                                                                                                                             | [`addStyle(String, boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#addStyle-java.lang.String-boolean-)                                                                                                                                                                                                                                                                                                                               | Superseded by ordinary CSS page-break control passed through `addStyle()` rather than a dedicated flag                                                                                                                                                                                      |
| `enableRenderingPatch(boolean)`                                                                                                                                                                                                                                                         | --                                                                                                                                                                                                                                                                                                                                                                                                                                             | No v4 successor listed                                                                                                                                                                                                                                                                      |
| `enableSmartTableBreaks(boolean)`                                                                                                                                                                                                                                                       | --                                                                                                                                                                                                                                                                                                                                                                                                                                             | No v4 successor listed                                                                                                                                                                                                                                                                      |
| `enableTableBreaks(boolean)`                                                                                                                                                                                                                                                            | --                                                                                                                                                                                                                                                                                                                                                                                                                                             | No v4 successor listed                                                                                                                                                                                                                                                                      |
| [`fitPageVertically()`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#fitPageVertically\(\))                                                                                                                                                                                     | [`fitPageVertically(int)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#fitPageVertically-int-)                                                                                                                                                                                                                                                                                                                                              | Now takes an explicit alignment constant                                                                                                                                                                                                                                                    |
| [`generateMulticolumn(int, int, boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#generateMulticolumn\(int,%20int,%20boolean\))                                                                                                                                           | [`generateMulticolumn(int, int, boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#generateMulticolumn-int-int-boolean-)                                                                                                                                                                                                                                                                                                                | Unchanged                                                                                                                                                                                                                                                                                   |
| [`generateOutlines(boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#generateOutlines\(boolean\))                                                                                                                                                                         | [`generateBookmarksFromHeadings(boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#generateBookmarksFromHeadings-boolean-) / [`generateBookmarksFromAnchors(boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#generateBookmarksFromAnchors-boolean-)                                                                                                                                                                            | Split into two purpose-specific methods (see the [Usage Examples' Create Bookmarks entry](https://app.gitbook.com/s/33dI66uC6sTAcaPjppX2/usage-examples))                                                                                                                                   |
| [`generatePdfa(boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#generatePdfa\(boolean\))                                                                                                                                                                                 | [`writePDF(OutputStream, String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#writePDF-java.io.OutputStream-java.lang.String-) with [`Constants.PDFA`](https://pd4ml.com/javadoc/com/pd4ml/Constants.html#PDFA)                                                                                                                                                                                                                            | Folded into the write call itself rather than a standalone flag set beforehand                                                                                                                                                                                                              |
| [`generatePdfForms(boolean, String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#generatePdfForms\(boolean,%20java.lang.String\))                                                                                                                                             | [`generateForms(boolean, String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#generateForms-boolean-java.lang.String-)                                                                                                                                                                                                                                                                                                                     | Renamed                                                                                                                                                                                                                                                                                     |
| [`getCache()`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#getCache\(\))                                                                                                                                                                                                       | [`getCache()`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#getCache--)                                                                                                                                                                                                                                                                                                                                                                      | Unchanged                                                                                                                                                                                                                                                                                   |
| [`getLastRenderInfo(String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#getLastRenderInfo\(java.lang.String\))                                                                                                                                                               | [`getLastRenderInfo(String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#getLastRenderInfo-java.lang.String-)                                                                                                                                                                                                                                                                                                                              | Unchanged                                                                                                                                                                                                                                                                                   |
| [`getVersion()`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#getVersion\(\))                                                                                                                                                                                                   | [`getVersion()`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#getVersion--)                                                                                                                                                                                                                                                                                                                                                                  | Unchanged                                                                                                                                                                                                                                                                                   |
| `interpolateImages(boolean)`                                                                                                                                                                                                                                                            | --                                                                                                                                                                                                                                                                                                                                                                                                                                             | No v4 successor listed (image interpolation is presumably automatic now)                                                                                                                                                                                                                    |
| [`isDemoMode()`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#isDemoMode\(\))                                                                                                                                                                                                   | [`isDemoMode()`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#isDemoMode--)                                                                                                                                                                                                                                                                                                                                                                  | Unchanged                                                                                                                                                                                                                                                                                   |
| [`isPro()`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#isPro\(\))                                                                                                                                                                                                             | [`isPro()`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#isPro--)                                                                                                                                                                                                                                                                                                                                                                            | Unchanged                                                                                                                                                                                                                                                                                   |
| [`merge(InputStream, int, int, boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#merge\(InputStream,%20int,%20int,%20boolean\)) / [`merge(Reader, int, int, boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#merge\(Reader,%20int,%20int,%20boolean\))     | [`merge(PdfDocument, int, int, boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#merge-com.pd4ml.PdfDocument-int-int-boolean-)                                                                                                                                                                                                                                                                                                         | Both v3 overloads consolidate onto one v4 overload taking a `PdfDocument`                                                                                                                                                                                                                   |
| [`monitorProgress(PD4ProgressListener)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#monitorProgress\(org.zefer.pd4ml.PD4ProgressListener\))                                                                                                                                   | [`monitorProgressWith(ProgressListener)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#monitorProgressWith-com.pd4ml.ProgressListener-)                                                                                                                                                                                                                                                                                                      | Renamed -- **but see the caveat immediately below the table**                                                                                                                                                                                                                               |
| [`outputFormat(String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#outputFormat\(java.lang.String\)) / [`outputFormat(String, int, int)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#outputFormat\(java.lang.String,%20int,%20int\))                               | [`writePDF(...)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#writePDF-java.io.OutputStream-) / [`writeRTF(...)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#writeRTF-java.io.OutputStream-boolean-) / [`renderAsImages()`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#renderAsImages--)                                                                                                                                            | The v3 "set a format flag, then render" model is replaced by calling the write method for the desired format directly                                                                                                                                                                       |
| [`outputRange(String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#outputRange\(java.lang.String\))                                                                                                                                                                           | [`outputRange(String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#outputRange-java.lang.String-)                                                                                                                                                                                                                                                                                                                                          | Unchanged                                                                                                                                                                                                                                                                                   |
| [`overrideDocumentEncoding(String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#overrideDocumentEncoding\(java.lang.String\))                                                                                                                                                 | [`overrideDocumentEncoding(String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#overrideDocumentEncoding-java.lang.String-)                                                                                                                                                                                                                                                                                                                | Unchanged                                                                                                                                                                                                                                                                                   |
| [`predictPageHeight(Insets, Dimension, int)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#predictPageHeight\(Insets,%20Dimension,%20int\))                                                                                                                                     | [`predictPageHeight(PageMargins, PageSize, int)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#predictPageHeight-com.pd4ml.PageMargins-com.pd4ml.PageSize-int-)                                                                                                                                                                                                                                                                              | Same purpose; parameter types updated to `PageMargins`/`PageSize`                                                                                                                                                                                                                           |
| [`predictScale(Insets, Dimension, int)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#predictScale\(Insets,%20Dimension,%20int\))                                                                                                                                               | [`predictScale(PageMargins, PageSize, int)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#predictScale-com.pd4ml.PageMargins-com.pd4ml.PageSize-int-)                                                                                                                                                                                                                                                                                        | Same purpose; parameter types updated to `PageMargins`/`PageSize`                                                                                                                                                                                                                           |
| [`protectPhysicalUnitDimensions()`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#protectPhysicalUnitDimensions\(\))                                                                                                                                                             | [`protectPhysicalUnitDimensions(boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#protectPhysicalUnitDimensions-boolean-)                                                                                                                                                                                                                                                                                                              | Now takes an explicit boolean instead of being an always-on toggle call                                                                                                                                                                                                                     |
| [`render(InputStreamReader, OutputStream[, URL])`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#render\(InputStreamReader,%20OutputStream\))                                                                                                                                    | [`readHTML(InputStream[, URL])`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#readHTML-java.io.InputStream-) + [`writePDF(OutputStream)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#writePDF-java.io.OutputStream-)                                                                                                                                                                                                                     | Splits into the two-phase model (§2)                                                                                                                                                                                                                                                        |
| [`render(String, OutputStream)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#render\(java.lang.String,%20OutputStream\)) / [`render(URL, OutputStream)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#render\(URL,%20OutputStream\))                                   | [`readHTML(URL)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#readHTML-java.net.URL-) + `writePDF(OutputStream)`                                                                                                                                                                                                                                                                                                                            | Splits into the two-phase model, source addressed as a URL                                                                                                                                                                                                                                  |
| [`render(StringReader, OutputStream[, URL[, String]])`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#render\(StringReader,%20OutputStream\))                                                                                                                                    | [`readHTML(InputStream, URL[, String])`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#readHTML-java.io.InputStream-java.net.URL-java.lang.String-) + `writePDF(OutputStream)`                                                                                                                                                                                                                                                                | Splits into the two-phase model, with an optional explicit source encoding                                                                                                                                                                                                                  |
| [`render(StringReader[], OutputStream, URL)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#render\(StringReader%5B%5D,%20OutputStream,%20URL\)) / [`render(URL[], OutputStream)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#render\(URL%5B%5D,%20OutputStream\))     | `readHTML(...)` + `writePDF(...)` per source, combined with [`PdfDocument.mergePDFs(InputStream, InputStream, OutputStream)`](https://pd4ml.com/javadoc/com/pd4ml/PdfDocument.html#mergePDFs-java.io.InputStream-java.io.InputStream-java.io.OutputStream-)                                                                                                                                                                                    | v3's "render several sources and merge them" array overloads are replaced by converting each source individually and merging the resulting PDFs explicitly                                                                                                                                  |
| [`renderAsImages(StringReader, URL, int, int)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#renderAsImages\(StringReader,%20URL,%20int,%20int\)) / [`renderAsImages(URL, int, int)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#renderAsImages\(URL,%20int,%20int\)) | `readHTML(...)` + one of [`renderAsImages()`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#renderAsImages--) / [`renderAsImages(File, String, String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#renderAsImages-java.io.File-java.lang.String-java.lang.String-) / [`renderAsImages(String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#renderAsImages-java.lang.String-)                                                         | Splits into the two-phase model, with a choice of in-memory, to-disk, or encoded-bytes image output                                                                                                                                                                                         |
| `resetAddedStyles()`                                                                                                                                                                                                                                                                    | --                                                                                                                                                                                                                                                                                                                                                                                                                                             | No v4 successor listed                                                                                                                                                                                                                                                                      |
| [`setAuthorName(String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setAuthorName\(java.lang.String\))                                                                                                                                                                       | [`setAuthorName(String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setAuthorName-java.lang.String-)                                                                                                                                                                                                                                                                                                                                      | Unchanged                                                                                                                                                                                                                                                                                   |
| [`setCache(PD4Cache)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setCache\(org.zefer.pd4ml.PD4Cache\))                                                                                                                                                                       | [`setCache(Object)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setCache-java.lang.Object-)                                                                                                                                                                                                                                                                                                                                                | Same purpose; parameter type loosened to `Object`                                                                                                                                                                                                                                           |
| [`setCookie(String, String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setCookie\(java.lang.String,%20java.lang.String\))                                                                                                                                                   | [`setCookie(String, String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setCookie-java.lang.String-java.lang.String-)                                                                                                                                                                                                                                                                                                                     | Unchanged                                                                                                                                                                                                                                                                                   |
| [`setDefaultTTFs(String, String, String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setDefaultTTFs\(java.lang.String,%20java.lang.String,%20java.lang.String\))                                                                                                             | [`addStyle(String, boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#addStyle-java.lang.String-boolean-)                                                                                                                                                                                                                                                                                                                               | Superseded by an ordinary CSS `@font-face` rule passed to `addStyle()` (see the [Usage Examples' Add Style Programmatically entry](https://app.gitbook.com/s/33dI66uC6sTAcaPjppX2/usage-examples))                                                                                          |
| [`setDocumentTitle(String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setDocumentTitle\(java.lang.String\))                                                                                                                                                                 | [`setDocumentTitle(String)`](https://pd4ml.tech/javadoc/com/pd4ml/PD4ML.html#setDocumentTitle-java.lang.String-)                                                                                                                                                                                                                                                                                                                               | Unchanged                                                                                                                                                                                                                                                                                   |
| [`setDynamicParams(Map)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setDynamicParams\(java.util.Map\))                                                                                                                                                                       | [`setDynamicData(Map)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setDynamicData-java.util.Map-) / [`setParam(String, String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setParam-java.lang.String-java.lang.String-) / [`setRenderingHints(Map)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setRenderingHints-java.util.Map-)                                                                                                 | v3's single, catch-all method splits into three narrower ones -- placeholder substitution values, individual named parameters, and rendering hints, respectively. **See the caveat below the table**, though: at least one other official example still calls `setDynamicParams()` under v4 |
| [`setHtmlWidth(int)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setHtmlWidth\(int\))                                                                                                                                                                                         | [`setHtmlWidth(int)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setHtmlWidth-int-)                                                                                                                                                                                                                                                                                                                                                        | Unchanged                                                                                                                                                                                                                                                                                   |
| [`setPageHeader(PD4PageMark)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setPageHeader\(org.zefer.pd4ml.PD4PageMark\)) / [`setPageFooter(PD4PageMark)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setPageFooter\(org.zefer.pd4ml.PD4PageMark\))                   | [`setPageHeader(String, int[, String])`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setPageHeader-java.lang.String-int-) / [`setPageFooter(String, int[, String])`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setPageFooter-java.lang.String-int-)                                                                                                                                                                                    | Replaced the callback object with a direct HTML string plus scope (§4)                                                                                                                                                                                                                      |
| [`setPageInsets(Insets)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setPageInsets\(Insets\)) / [`setPageInsetsMM(Insets)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setPageInsetsMM\(Insets\))                                                                   | [`setPageMargins(PageMargins[, String])`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setPageMargins-com.pd4ml.PageMargins-)                                                                                                                                                                                                                                                                                                                | The separate points/millimeters methods collapse into one call; units are now chosen via the `PageMargins` constructor instead of which method you call                                                                                                                                     |
| [`setPageSize(Dimension)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setPageSize\(Dimension\)) / [`setPageSizeMM(Dimension)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setPageSizeMM\(Dimension\))                                                               | [`setPageSize(PageSize[, String])`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setPageSize-com.pd4ml.PageSize-)                                                                                                                                                                                                                                                                                                                            | Same collapse as `setPageMargins`, for page size instead of margins                                                                                                                                                                                                                         |
| [`setPermissions(String, int, boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setPermissions\(java.lang.String,%20int,%20boolean\))                                                                                                                                     | [`setPermissions(String, int)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setPermissions-java.lang.String-int-)                                                                                                                                                                                                                                                                                                                           | Trailing legacy-mode boolean dropped (see the [Usage Examples' Set Document Password entry](https://app.gitbook.com/s/33dI66uC6sTAcaPjppX2/usage-examples))                                                                                                                                 |
| [`setSessionID(String)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#setSessionID\(java.lang.String\))                                                                                                                                                                         | [`setSessionID(String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#setSessionID-java.lang.String-)                                                                                                                                                                                                                                                                                                                                        | Unchanged                                                                                                                                                                                                                                                                                   |
| [`translate(int)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#translate\(int\))                                                                                                                                                                                               | [`translateToPt(float)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#translateToPt-float-)                                                                                                                                                                                                                                                                                                                                                  | Renamed, and now takes/returns a `float` rather than an `int`                                                                                                                                                                                                                               |
| `useAdobeFontMetrics(boolean)`                                                                                                                                                                                                                                                          | --                                                                                                                                                                                                                                                                                                                                                                                                                                             | No v4 successor listed                                                                                                                                                                                                                                                                      |
| [`useHttpRequest(HttpServletRequest, HttpServletResponse)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#useHttpRequest\(HttpServletRequest,%20HttpServletResponse\))                                                                                                           | [`useHttpRequest(HttpServletRequest, HttpServletResponse)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#useHttpRequest-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-)                                                                                                                                                                                                                                       | Unchanged                                                                                                                                                                                                                                                                                   |
| [`useServletContext(ServletContext)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#useServletContext\(ServletContext\))                                                                                                                                                         | [`useHttpRequest(...)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#useHttpRequest-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-)                                                                                                                                                                                                                                                                           | Folded into `useHttpRequest()`                                                                                                                                                                                                                                                              |
| [`useTTF(String, boolean)`](https://old.pd4ml.com/api/org/zefer/pd4ml/PD4ML.html#useTTF\(java.lang.String,%20boolean\))                                                                                                                                                                 | [`useTTF(String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#useTTF-java.lang.String-) / [`useTTF(String, boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#useTTF-java.lang.String-boolean-) / [`useTTF(String, String)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#useTTF-java.lang.String-java.lang.String-) + [`embedTTFs(boolean, boolean)`](https://pd4ml.com/javadoc/com/pd4ml/PD4ML.html#embedTTFs-boolean-boolean-) | The single v3 overload expands into three v4 overloads for different addressing needs, with glyph-embedding behavior configured separately via `embedTTFs()` (see the [Usage Examples' i18n section](https://app.gitbook.com/s/33dI66uC6sTAcaPjppX2/usage-examples))                        |

{% hint style="warning" %}
**Two entries in this table conflict with tested example code published elsewhere on pd4ml.com**, and are worth double-checking against the actual Javadoc for the PD4ML build in use before relying on them:

* **`monitorProgress`/`monitorProgressWith`** -- this migration guide lists v3 as `monitorProgress(PD4ProgressListener)` and v4 as `monitorProgressWith(ProgressListener)`. The [Usage Examples' Add Progress Listener entry](https://app.gitbook.com/s/33dI66uC6sTAcaPjppX2/usage-examples), however, shows the _opposite_ pairing in its tested v3/v4 code samples: v3 calling `monitorProgressWith(ProgressListener)` and v4 calling `monitorProgress(PD4ProgressListener)`.
* **`setDynamicParams`** -- this migration guide lists it as v3-only, superseded in v4 by `setDynamicData`/`setParam`/`setRenderingHints`. The [Usage Examples' Add Custom Resource Loader entry](https://app.gitbook.com/s/33dI66uC6sTAcaPjppX2/usage-examples), however, calls `pd4ml.setDynamicParams(map)` directly in its v4 code sample.

Both discrepancies come from pd4ml.com's own published documentation rather than from anything in this rewrite -- they're surfaced here rather than silently resolved one way or the other.
{% endhint %}

## See also

* [PD4ML Programmer's Manual](https://app.gitbook.com/s/33dI66uC6sTAcaPjppX2/) -- the current (v4) API, described from scratch rather than as a diff against v3.
* [Usage Examples](https://app.gitbook.com/s/33dI66uC6sTAcaPjppX2/usage-examples) -- runnable examples with v3 and v4 code shown side by side for most common tasks.
* [Support Forums](https://pd4ml.com/forums/) and [Extended Support Plans](https://pd4ml.com/pd4ml-extended-support-plans/) -- for migration questions not covered here.
