| 2026-11-07 | v4.2.0 | Improvement | v42 applies OpenType GSUB/GPOS features itself: ligatures, small caps, figure styles, kerning, font-feature-settings and the other CSS font-variant properties. Vertical text (writing-mode) as in Chrome: vertical glyph forms and metrics, column wrapping, mixed scripts, text-combine-upright. DOCX/RTF carry both as Word's own OpenType settings and vertical text; DOCX can embed fonts (pd4ml.docx.embed.fonts). |
| 2026-11-06 | v4.2.0 | Bug fixed | A static code analysis of v4.2.0 found no serious issues. The few findings are fixed, and unused code is removed.
|
| 2026-11-06 | v4.2.0 | Improvement | New method PD4ML.addAllowedResourceLocation(String) limits the locations PD4ML loads stylesheets, images, web fonts and attachments from - a security measure for HTML from untrusted sources (local files, internal services). The same restriction as PD4ML_ALLOWED_RESOURCE_LOCATION param, as a method. |
| 2026-11-06 | v4.2.0 | Improvement | A generated pd4fonts.properties lists which characters each font file has, so PD4ML no longer loads font files that cannot display the text when it looks for a fallback font. Font lookup is several times faster with a large font directory. Regenerate existing mapping files with java -jar pd4ml.jar -configure.fonts |
| 2026-11-06 | v4.2.0 | Bug fixed | With built-in PDF fonts, text after a character the font cannot write no longer overlaps the "?" drawn for it (v42 engine). The hyphen (U+2010) and non-breaking hyphen (U+2011) now appear as a regular hyphen instead of "?" in PDF output, and instead of an empty box in v40 image output. |
| 2026-11-06 | v4.2.0 | Improvement | Khmer text wraps (v42 engine): lines break between syllables, as Khmer has no spaces between words. |
| 2026-11-06 | v4.2.0 | Bug fixed | DOCX and RTF output (v40 engine) wrote font sizes up to 1pt too small (cut to a whole point: 12pt text as 11pt), and protectPhysicalUnitDimensions() made physical sizes about four times too small there instead of keeping them true to size. |
| 2026-11-06 | v4.2.0 | Improvement | watermarks (setWatermark(), |
| 2026-11-06 | v4.2.0 | Improvement | with generateForms(true, ...) every form field now carries its own appearance - text, password, textarea, combo and list box values are shown in every viewer, including those that do not regenerate field appearances (print, flattening, PDFBox), and Acrobat no longer asks to save a document that was only read. |
| 2026-11-06 | v4.2.0 | Improvement | The PDF optimizer can write linearized ("Fast Web View") PDF, so a viewer loading the file over a network shows the first page, and then any other page, before the whole file has arrived: pd4optimizecli --linearize or PdfOptimizer.Options.linearize(true). A PDF 1.5+ document is written linearized with object streams and cross-reference streams. Linearized output cannot be combined with output encryption. Bug fixed: the PDF optimizer (and merger, XFDF import) no longer makes PDF 1.5+ files several times larger - objects are written in compressed object streams with a cross-reference stream, as PD4ML writes its own PDFs; the COS parser reads a compressed object from the object stream its cross-reference entry names. Bug fixed: optimizing or linearizing a PDF/A file keeps it compliant - PDF/A-1 keeps classic cross-reference tables (PD4ML writes it with a 1.7 header), and the file identifier (/ID) is no longer dropped. |
| 2026-11-06 | v4.2.0 | Improvement | emoji and color fonts (COLR v0/CPAL vector, CBDT/CBLC bitmap - e.g. Twemoji, Noto Color Emoji, Segoe UI Emoji) are drawn in color in PDF and image output, ZWJ sequences, skin tones and flags as single glyphs, and stay selectable/copyable; an emoji font of the font set is used as fallback automatically; the optional com.pd4ml:pd4ml-emoji add-on (Twemoji; Maven repository and distribution zip) enables emoji with no setup. |
| 2026-11-06 | v4.2.0 | Improvement | CSS gradient backgrounds (linear, radial, conic, repeating; tiled, sized and positioned like images; with transparency) in both layout engines, written to PDF as vector shadings - before, v42 drew a gradient as a black box and v40 ignored it; v42 body/html background images and gradients now also fill every page. In v42 DOCX/RTF output gradients are the word processor's own gradient fills (also on table cells and inline elements), not pictures. |
| 2026-11-06 | v4.2.0 | Improvement | CSS multi-column layout (v42): a multi-column section longer than the rest of its page now continues page by page, filling the columns of each page before it moves on, instead of being cut across all columns by the page break; column-span: all headings run across the full width between two independently balanced column sets; boxes with break-inside: avoid that do not fit a column move to the next one; column rules are drawn on every page. |
| 2026-11-06 | v4.2.0 | Improvement | E-mail messages (.eml) and saved web pages (.mht, .mhtml) can be converted with readEML() and readMHT(), and readHTML() recognizes them automatically. Resources load from https:// only, unless addAllowedResourceLocation() sets another list. The attachments of a message are embedded as PDF attachments. |
| 2026-11-06 | v4.2.0 | Improvement | Smaller and faster-loading PDF output with the same look: small objects are stored compressed in object streams with a compressed cross-reference stream (PDF 1.5 and later; not for PDF/A-1 and encrypted output), pages are organised as a tree of at most 10 entries per node, and page content and dictionaries no longer contain redundant operators or default-value entries. -Dpd4ml.objectStreams=false and -Dpd4ml.optimizeContent=false restore the previous output. |
| 2026-11-06 | v4.2.0 | Improvement | DOM API (com.pd4ml.dom, v42 engine): getDocument() reads and changes the parsed HTML before the output - CSS selectors, attributes, inner HTML, style sheets; layout() reports page count, each element's boxes per page and computed styles without writing the document. |
| 2026-11-06 | v4.2.0 | Improvement | With the v42 engine, DOCX and RTF output is written from the same layout as the PDF - same lines, page breaks and spacing - as editable paragraphs and tables; positioned boxes as text boxes, native SVG (DOCX) and native check boxes. |
| 2026-11-06 | v4.2.0 | Improvement | New layout engine v42 (useHtmlRenderer(LayoutEngine.v42); v40 stays the default): Chrome-verified HTML5/CSS layout with Flexbox, CSS Grid, multi-column, vertical writing modes, @page named pages and margin boxes, richer PDF/UA tagging. Improvement: accessible DOCX and RTF with a PD4ML/UA license (v42 engine): headings as Word heading styles, table header rows, the document language, image alt text and decorative images; without the UA license, Word output carries no alt text, title or accessibility structure. |
| 2026-11-01 | v4.1.2 | RELEASE | v4.1.2 is released and available for download |
| 2026-11-01 | v4.0.24 | RELEASE | v4.0.24 is released and available for download |
| 2026-11-01 | v3.12.0 | RELEASE | v3.12.0 is released and available for download |
| 2026-10-30 | v4.0.24 v4.1.2 | Bug fixed | Buttons of different heights in one line are aligned on the baseline of their text, as in browsers, instead of on their top edges. |
| Improvement | New method PD4ML.addMetadata(namespaceURI, prefix, key, value) adds custom XMP metadata properties in a namespace of your own, for example the W3C TDM Reservation Protocol properties tdm:reservation and tdm:policy. In PDF/A output the namespace is declared in a PDF/A extension schema, so the document stays valid. Bug fixed: XMP metadata values containing &, < or > (title, author, keywords, custom properties) no longer get a stray "\u" before the character. | ||
| Bug fixed | In tagged PDF output (PDF/UA, PDF/A-1a/2a/3a), MathML formulas are now tagged as Formula structure elements instead of being marked as artifacts, so screen readers no longer skip them. | ||
| 2026-10-29 | v4.0.24 | Bug fixed | Unwanted line break before superscript/subscript text that immediately follows regular text without a space. |
| 2026-10-28 | v3.12.0 | Bug fixed | The CSS ::before (and :before) pseudo-element with a string content value, including CSS hex escapes such as \e8b8, is now rendered in PDF, PDF/A and RTF output instead of being ignored. (HELPD-656) |
| Bug fixed | A page background image given as a Windows file path such as D:/dir/img.jpg or D:\dir\img.jpg is no longer silently ignored, and short background values no longer cause an exception. (HELPD-593, HELPD-592) | ||
| Bug fixed | In PDF/A output, transparent areas of images are now rendered white instead of black, so transparent logos and watermark images no longer produce black boxes. (HELPD-803, HELPD-797, HELPD-810) | ||
| Bug fixed | Image and device objects are no longer held back by finalizers, so memory is released sooner in long-running servers. (HELPD-839) | ||
| Bug fixed | Memory consumption when writing large PDF documents is reduced: compressed streams no longer allocate a buffer of twice their size, and fewer temporary strings are created. (HELPD-806) | ||
| Bug fixed | The system property pd4ml.fake.browser now also applies to resources loaded over https, so images from servers that reject Java's default User-Agent are no longer dropped. (HELPD-468) | ||
| Bug fixed | In RTF output, list items with several blocks keep their bullet on the first line, and an item following an inline list item gets its own bullet. (HELPD-867) | ||
| 2026-10-28 | v4.0.24 v4.1.2 | Improvement | Robustness and performance (from a run over a large real-world document corpus)
|
| Bug fixed | A fieldset whose top falls near the page bottom is moved to the next page together with its legend, instead of leaving the legend and the top border alone at the bottom of the page. (HELPD-874) | ||
| Bug fixed | OpenType fonts with PostScript (CFF) outlines (.otf, e.g. Noto Sans CJK) are now embedded as a font subset instead of the whole font file, so a PDF with a CJK font of 15 MB is a few hundred KB instead of 23 MB. (HELPD-798) | ||
| Improvement | generateMulticolumn() (and the -multicolumn command line option / multicolumn taglib attribute) now produces multi-column PDF output as in PD4ML v3: the content flows through the given number of columns per page, a page break moves to the next column, <pd4ml:page.break multicolumn="true"> starts a new page, page headers and footers are placed once per page and $[page] / $[total] count PDF pages. (HELPD-778, HELPD-795, HELPD-805) | ||
| 2026-10-17 | v4.1.2 | Bug fixed | ported all fixes from v4.0.24’s Large-scale backlog cleanup to v4.1.2 |
| 2026-10-17 | v4.0.24 | Bug fixed | PDF and XMP dates include the daylight saving time offset (e.g. +02'00' under CEST). |
| Bug fixed | PDF/A: setting only pd4ml.document.date sets the XMP dates too, so the output no longer fails veraPDF rule 6.7.3-1. | ||
| Bug fixed | Text inputs (text, password, email, search, tel, url, number) without an explicit width now get the browser's default width: size (default 20) average characters plus the widest-character allowance, plus padding and border; they used to be too narrow by default and too wide with a size attribute. (HELPD-647) | ||
| Bug fixed | Unstyled text inputs now use the browser default style (13.333px font, 1px 2px padding, a 2px border drawn as a 1px gray frame), so they get the same size as in browsers; padding and border are no longer added twice to their width, and a border with border-style: none no longer counts toward an input's size. (HELPD-647) | ||
| Bug fixed | Flex items sized to their content no longer take the full container width when they contain an element with a percentage width, min-width or max-width; as in browsers, the percentage counts as auto while the item is measured and then resolves against the item's final width. (HELPD-647) | ||
| Bug fixed | Table cells: the max-width of blocks in cells is applied, percentage margins in fixed-width cells no longer widen the table, a fixed-width column is as wide as its width (at least its min-content width) instead of its content's max-content width, and spanning cells (colspan) over fixed-width columns are no longer ignored. (HELPD-647) Bug fixed: A table-layout: fixed table with a percentage width inside an auto-width table cell now fills the cell, as in browsers, instead of collapsing it. (HELPD-647) Bug fixed: Floats, inline-blocks and absolutely positioned boxes whose content wraps (because of the available width or their max-width) now take that full width instead of the width of their widest line, so aligned text lines up with the box edge, and inline elements no longer lose their container's margins, borders and paddings twice from their available width. (HELPD-647) | ||
| Bug fixed | In quirks mode (no doctype, or a legacy one) tables no longer inherit the font size, weight, style, variant, line height and white-space of their surroundings, as in browsers; for example, text in a table inside <font size=5> now has the default size. (HELPD-647) | ||
| Bug fixed | A float with a percentage width, min-width or max-width inside a float, inline-block or absolutely positioned box no longer makes that box too wide or too narrow: as in browsers, the box sizes itself with the float at auto width and the percentage resolves against the result. (HELPD-647) Bug fixed: A float, inline-block, absolutely positioned box or auto-width table cell containing text followed by a float on the same line is now wide enough for both, so the text no longer wraps below the float. (HELPD-647) | ||
| Bug fixed | Text in the built-in Helvetica, Times and Courier fonts (no TTF embedding) is now placed on the same baseline as the browser's Arial, Times New Roman and Courier New, about 1pt lower than before, so it is vertically centered in table cells as on screen. (HELPD-769) | ||
| Bug fixed | A block with a percentage min-width or percentage horizontal margins, a percentage or auto-width <hr>, a block with a width of 100% or more, or a percentage-width table inside a float, inline-block, absolutely positioned box or auto-width table cell no longer stretches that box to the page width or beyond: as in browsers, the box sizes to its content and the percentages resolve against the result. (HELPD-647) Bug fixed: Horizontal rules (<hr>) now follow the browser box model: a percentage or fixed width is the width of the line, with borders and padding added on top, a rule without a width fills its container including its borders instead of overflowing it by 2px, and rules in DOCX and RTF output get their exact specified width. (HELPD-647) | ||
| Bug fixed | A rounded-corner cell background (border-radius) no longer shows a faint seam next to a square neighbour with the same background. (HELPD-601) | ||
| Bug fixed | In the built-in SVG renderer, text-anchor (middle, end) is now applied to a <text> element without an x attribute, so end-anchored or rotated (vertical) SVG text is no longer shifted off the image or missing. | ||
| Bug fixed | A block with a percentage width, max-width or padding inside a float, inline-block, absolutely positioned box or auto-width table cell no longer stretches that box to the page width or beyond: as in browsers, the box sizes to its content and the percentage resolves against the result. Bordered or padded blocks inside floats no longer wrap their text. (HELPD-647) | ||
| Bug fixed | A word that continues across an inline element boundary (for example <em>word</em>. or <a>link</a>,) is no longer split at the line end, so lines no longer start with stray punctuation. (HELPD-791) | ||
| Bug fixed | Form controls (input, select, textarea, button) and images with a percentage width inside a float, inline-block, absolutely positioned box or auto-width table cell no longer stretch that container to the full available width; as in browsers, the container is sized to the element's natural width and the percentage applies to it, and an <img width="100%"> in an auto-width table cell no longer disappears. (HELPD-647) | ||
| Bug fixed | Title and page number alignment in headers and footers defined with the v3 API or the JSP taglib (PD4PageMark) is no longer overridden by document CSS such as td { text-align: left; }. (HELPD-530) | ||
| Bug fixed | In RTF output, empty table cells without padding are no longer written with a zero width, which made MS Word show the document as a single page and fail to export it to PDF. (HELPD-519) | ||
| Bug fixed | Each embedded TrueType font subset in a PDF now gets its own subset tag, so documents using emulated (synthetic) italic or bold, several sizes of one font, or the pd4ml.document.id property no longer contain different font programs with the same name, which made Adobe Acrobat stop rendering the document. (HELPD-848) | ||
| Bug fixed | DOCX output of list items containing blocks (tables, nested lists, empty blocks, blocks after links) is well-formed and opens in Word; table grid columns are never zero-width. (HELPD-519) | ||
| Bug fixed | Concurrent conversions with fonts loaded from the classpath (useTTF("java:...")) no longer use partially written or empty temporary font files, which made text lose its font. (HELPD-554) | ||
| Bug fixed | Custom metadata added with addMetadata() keeps PDF/A output valid: custom properties get a PDF/A extension schema description, and hidden properties are written in their own namespace. (HELPD-283) | ||
| Bug fixed | The PDF document language (/Lang) is taken from <html lang> when <body> has no lang attribute, instead of always "en". (HELPD-716) | ||
| Bug fixed | In collapsed-border tables, 1px cell borders next to rowspan cells are no longer hidden by neighbouring cell backgrounds, and a table moved to the next page keeps its top border. (HELPD-792) Bug fixed: In table cells, the top margin of the first block and the bottom margin of the last block (e.g. <p style="margin-bottom: 8pt">) now count as in browsers, so table rows are no longer tighter than on screen; only in quirks mode (no or a legacy doctype) are the default margins of a leading or trailing paragraph, heading or list dropped, as browsers do. (HELPD-792) | ||
| Bug fixed | With the v3-compatible API, a page background image or color and a watermark set on a PD4PageMark without a title or page number template are no longer ignored. (HELPD-592, HELPD-593) | ||
| Bug fixed | SVG stroke-dasharray is honored in PDF output: dash and gap lengths follow the SVG, a zero-gap pattern (e.g. "6 0") draws a solid line, and solid strokes after dashed ones stay solid. (HELPD-423, HELPD-497) | ||
| Bug fixed | Arabic text in fonts without Arabic presentation forms (e.g. Haradh) is shaped with the font's own layout tables instead of being shown as ? or in a fallback font. (HELPD-710) | ||
| Bug fixed | Thai and Lao text is shaped with the font's layout tables, so tone marks stacked above vowels are positioned correctly instead of overlapping or being detached. (HELPD-521) | ||
| Bug fixed | In left-to-right paragraphs, the space between a right-to-left word and the following left-to-right text stays between them instead of being moved before the right-to-left word. (HELPD-431) | ||
| Bug fixed | Absolute font file paths and URLs in pd4fonts.properties are used as they are instead of being resolved against the font directory. (HELPD-465) | ||
| Bug fixed | An element with display: table-cell inside a table cell no longer breaks the table structure, and percentage heights and max-width of floats and flex items resolve against the correct container. (HELPD-579) Bug fixed: With box-sizing: border-box, percentage heights and min/max-heights now include the box's padding and border as in browsers, max-height also limits an explicit height, and percentage heights resolve against the parent's content height. (HELPD-579) | ||
| Bug fixed | A heading with page-break-after: avoid moves to the next page together with the following block instead of being left alone at the bottom of a page. (HELPD-307) | ||
| Bug fixed | Text marked white-space: nowrap stays on one line in table cells, also when it is split by font fallback or nested inline elements (e.g. "€ 30,50"). (HELPD-448) | ||
| Bug fixed | A text <input> inside an absolutely positioned element keeps its default or explicit width instead of being painted as a sliver. (HELPD-780) | ||
| Bug fixed | A width: 100% table inside a box with margins, borders or padding is no longer narrowed by subtracting the box's spacing twice. (HELPD-843) | ||
| Bug fixed | <pd4ml:page.break ifSpaceBelowLessThan> is honored on pages that end with an explicit page break, so a footnote no longer lands on the next section's page. (HELPD-838) | ||
| Bug fixed | A <pd4ml:page.footer> or header defined further down in the document applies from the page where it is defined instead of appearing on page 1. (HELPD-834) | ||
| Bug fixed | In RTF output, a styled <hr> is drawn in its CSS border or background color instead of always black. (HELPD-611) | ||
| Bug fixed | In RTF output, sidebar-style blocks with a background and padding are rendered as one shaded box with their padding, without extra white space. (HELPD-817) | ||
| Bug fixed | Absolutely positioned content taller than a page is paginated completely again instead of being cut off after the in-flow content ended. (HELPD-474) | ||
| Bug fixed | merge() no longer fails with "Parsing of PDF failed" (ClassCastException) on PDFs whose document information (/Info) or outline entries are stored as indirect objects. (HELPD-145) | ||
| Bug fixed | Encrypted PDFs without a document ID (/ID) are decrypted correctly when loaded, so saving or overlaying them (e.g. adding a watermark) no longer produces empty pages. (HELPD-706) | ||
| Bug fixed | In RTF output, paragraphs (<p>, <div>) inside table cells and list items are written as regular paragraphs again instead of nested tables, so list bullets stay on the same line as their text. (HELPD-814, HELPD-815) | ||
| Bug fixed | In RTF output, consecutive block elements (e.g. <div>) inside a table cell, including page header/footer tables, are separated by a paragraph break again instead of being merged onto one line. (HELPD-724, HELPD-725, HELPD-726, HELPD-727, HELPD-816) | ||
80 (cached 2026-11-07 19:45)
