Releases: py-pdf/fpdf2
Releases · py-pdf/fpdf2
New methods table() and set_fallback_fonts() - keep_aspect_ratio - ICC Profiles
Added
- new method
FPDF.table()
: documentation FPDF.image()
has a newkeep_aspect_ratio
optional boolean parameter, to fit it inside a given rectangle: documentationFPDF.multi_cell()
andFPDF.write()
now accept awrapmode
argument for word or character based line wrapping ("WORD"/"CHAR").- new methods:
FPDF.preload_image()
&FPDF.use_font_style()
- new method
FPDF.set_fallback_fonts()
allow alternative fonts to be provided if a character on the text is not available on the currently set font - thanks to @andersonhc - for inserted images that have an ICC Profile, this profile is now extracted and embedded; they should now be honored by PDF viewers - thanks to @eroux
- new translation of the tutorial in 简体中文 - thanks to @Bubbu0129
- documentation on how to embed static Plotly charts: link to docs
- additional linter / static code analyser in GitHub Actions CI pipeline: semgrep
Fixed
- outlines & hyperlinks were not working on encrypted files - thanks to @andersonhc
- a bug was introduced in the previous release (2.6.1):
FPDF.set_link()
could not update links generated withadd_link()
- unicode (non limited to ASCII) text can now be provided as metadata #685
- all
TitleStyle
constructor parameters are now effectively optional - memory usage was reduced by 10 MiB in some cases, thanks to a small optimization in using
fonttools
Changed
FPDF.write_html()
now uses the newFPDF.table()
method to render<table>
tags. As a consequence, vertical space before<table>
tags has sometimes been reduced.
- vector images parsing is now more robust:
fpdf2
can now embed SVG files withoutviewPort
or noheight
/width
- bitonal images are now encoded using
CCITTFaxDecode
, reducing their size in the PDF document - thanks to @eroux - when possible, JPG and group4 encoded TIFFs are now embedded directly without recompression - thanks to @eroux
Removed
FPDF.write_html()
now uses the newFPDF.table()
method to render<table>
tags. As a consequence, it does not support theheight
attribute defined on<td>
/<th>
tags anymore, norheight
/width
attributes defined on<img>
tags inside cells, norwidth
attributes defined on<thead>
/<tfoot>
tags.
PDF encryption - skewing - markdown hyperlinks - Python 3.11
Added
- support for PDF encryption (RC4 and AES-128): documentation page - thanks to @andersonhc
FPDF.skew()
- New method: documentation page - thanks to @erap129- ensured support for Python 3.11
FPDF.image()
: thex
parameter now accepts a value of"C"
/Align.C
/"R"
/Align.R
to horizontally position the image centered or aligned rightFPDF.image()
: dimensions can now be provided to set the intrinsic image width & height before storing it in the PDFFPDF.cell()
&FPDF.multi_cell()
: support for[]()
hyperlinks whenmarkdown=True
FPDF.write_html()
: support forline-height
attribute of paragraph (<p>
) - thanks to @Bubbu0129- documentation on useful tools to manipulate PDFs
- show a warning if the font being used doesn't have all the necessary glyphs for the text
Changed
FPDF.add_link()
creates a link to the current page by default, and now accepts optional parameters:x
,y
,page
&zoom
.
Hence callingset_link()
is not needed anymore after creating a link withadd_link()
.FPDF.write_html()
now generates warnings for unclosed HTML tags, unlesswarn_on_tags_not_matching=False
is set
Fixed
FPDF.write_html()
: aValueError: Incoherent hierarchy
could be raised with some headings hierarchyFPDF.write_html()
:<img>
withoutheight
attribute overlaps with the following content #632 - thanks to @Bubbu0129FPDF.image()
: performance issue with adding large images withFlateDecode
image filter #644 - thanks to @Markovvn1FPDF.add_font()
: fix support for upper case font file name #638 - thanks to @CY-Qiu
HTMLMixin not needed anymore - more HTML tags supported - demonstration Jupyter notebook
Added
- demonstration Jupyter notebook: tutorial/notebook.ipynb
- new
.default_page_dimensions
property onFPDF
instances - support for description list (
<dl>
), description titles (<dt>
), description details (<dd>
) and code blocks (<code></code>
) inwrite_html()
- thanks to @yk-jp & @seanpmulholland - support for monochromatic images (PIL
image.mode == '1'
) thanks to @GerardoAllende - the 1000+ unit tests suite is now executed under Linux and Windows, with extra timing & memory usage checks ensuring we control
fpdf2
resource usage - new translation of the tutorial in עברית, thanks to @TzviGreenfeld
- new documentation for using PyPDF2 with
fpdf2
, added by @devdev29: https://pyfpdf.github.io/fpdf2/CombineWithPyPDF2.html - new documentation for using Jinja with
fpdf2
: https://pyfpdf.github.io/fpdf2/TemplatingWithJinja.html
Deprecated
HTMLMixin
is deprecated, and not needed anymore: thewrite_html()
method is now natively available in theFPDF
class - thanks to @yk-jp
Removed
open()
&close()
methods, that were only used internally and should never have been called by end-user codeFPDF.state
, which was an instance of theDocumentState
enum, and has been replaced by moving the final rendering logic into a newfpdf.output
module
Fixed
- after an "empty"
cell()
,ln()
applied a line height of zero #601 - when using
multi_cell()
withmax_line_height
to render multiline text, the last line is now rendered like all the others - templates don't leak graphics state changes to their surroundings anymore; #570
- automatic page break is never performed on an empty page (when the Y position is at the top margin)
- fixed
insert_toc_placeholder()
usage withfooter()
and{{nb}}
; #548 - the SVG parser now accepts
stroke-width
attribute values with an explicit unit, thanks to @gmischler; #526 - the SVG parser now accepts absolute units for
width
andheight
attributes, thanks to @darioackermann; #555 write_html()
method now correctly handles whitespace when parsing HTML.<pre></pre>
blocks still maintain spaces, tabs and line breaks.
Changed
- the first parameter of
FPDF.add_font()
is now optional: if it is not provided, the base name of thefname
font path is used to define the font family. Hencepdf.add_font(fname="fonts/NotoSansArabic.ttf")
will define a font namedNotoSansArabic
. - the output of
embed_file()
is now aPDFEmbeddedFile
, not a string, but the internal file name can be retrieved through its.basename
property - forbid use of
get_y()
&local_context()
insideunbreakable()
as it is currently not supported; #557 - fontTools minimal version requirement set to 4.34.0; #524
Support for subscript & superscript - set_page_background - embed_file - set_char_spacing
Added
- Added support for subscript, superscript, nominator and denominator char positioning as well as
<sub>
and<sup>
HTML tags, thanks to @gmischler: link to documentation set_page_background()
: new method added by @semaeostomea: link to documentationembed_file()
&file_attachment_annotation()
: new methods to add file attachments - link to documentation- A new method
set_char_spacing()
allows to increase the spacing between individual characters, thanks to @gmischler: link to documentation - workaround by @semaeostomea to support arabic and right-to-left scripts: link to documentation
- documentation on shapes styling: link to documentation
- documentation on sharing the images cache among FPDF instances: link to documentation
Changed
- HTML headings are now rendered with an additional leading of 20% the font size above and below them; #520
fpdf2
now uses fontTools to read and embed fonts in the PDF, thanks to @gmischler and @RedShy
Fixed
- Text following a HTML heading can't overlap with that heading anymore, thanks to @gmischler
arc()
not longer renders artefacts at intersection point, thanks to @Jmillan-Dev; #488write_html()
:- the
CreationDate
of PDFs & embedded files now includes the system timezone
PDF document signing - greek tutorial - better SVG image parsing
Added
- new methods to allow signing PDF documents: link to docs
- support for colors defined with the
rgb()
syntax in SVG images - cf. #480 - New translation of the tutorial in Ελληνικά, thanks to @sokratisvas
Changed
- an
/ID
is now inserted in the trailer dictionary of all PDF documents generated.
This ID can be controlled through the new file_id() method. - the svg.path package was added as a dependency to better parse SVG images
Fixed
font_stretching
doesn't make text spill out ofmulti_cell()
andwrite()
boundaries anymore, thanks to @gmischlerlocal_context()
now always restores the correct font settings after finishing, thanks to @gmischler- properly parsing single-digits arguments in SVG paths - cf. #450
- document outline encoding: it was found to be broken when using a thai font - cf. #458
Parsing of SVG files with CSS styling, FPDF.rect() with round_corners, FPDF.star()
Added
- a new option
align="X"
to.cell()
and.multi_cell()
allows to center text around the current x position, thanks to @gmischler - allowing to provide an
AnnotationName
andAnnotationFlags
onto text_annotation() - allowing correctly parsing of SVG files with CSS styling (
style="..."
attribute), thanks to @RedShy FPDF.star()
: new method added to draw regular stars, thanks to @digidigital and @RedShyFPDF.ink_annotation()
: new method added to add path annotations- allowing embedding of indexed PNG images without converting them to RGB colorspace, thanks to @RedShy
- allowing to change appearance of highlight annotations by specifying a
TextMarkupType
- documentation on how to control objects transparency: link to docs
- documentation on how to create tables and charts using pandas DataFrames: link to docs, thanks to @iwayankurniawan
- added argument
round_corners
toFPDF.rect()
that allows to draw rectangles with round corners: link to docs - thanks to @gonzalobarbaran
Fixed
- support for
"x"
&"y"
attributes in SVG<use>
tags - cf. #446 CreationDate
of PDFs generated, that was broken - cf. #451multi_cell()
andwrite()
ignored a trailing newline character in the supplied text since 2.5.1 - fixed thanks to @gmischler
New .page_mode & .viewer_preferences properties
Added
- new
FPDF.page_mode
property, allowing to display a PDF in full screen: link to docs - new
FPDF.viewer_preferences
property: link to docs
Fixed
- removed a debug
print()
statement (multi_cell: new_x=... new_y=...
) that had been left in multi_cell() method 🤦♂️ - preserved backward compatibility with PyFPDF for passing positional arguments to
cell()
&multi_cell()
, which was broken in 2.5.2
Modified
- when
regular_polygon()
is called withstyle="f"
,
the shape outline is not drawn anymore. Usestyle="DF"
to also draw a line around its perimeter.
Deprecated
- the
fill
parameter of thepolygon()
&polyline()
methods have been replaced by astyle
argument,
offering more control
New image clipping methods
Added
- new
round_clip()
&elliptic_clip()
image clipping methods: link to docs CoerciveEnum
subclasses have been added:Align
&RenderStyle
- documentation on how to embed Matplotlib charts: link to docs
- documentation on how to use
fpdf2
with Flask, streamlit, AWS lambdas: link to docs - documentation on how to store PDFs in a database with SQLAlchemy: link to docs
Modified
TextMode
,XPos
&YPos
now inherit fromCoerciveEnum
and hence can simply be passed as string parameters
Fixed
- infinite loop when calling
.multi_cell()
without enough horizontal space - cf. #389
Removed
- support for
.pkl
files passed toadd_font()
. This was deprecated since v2.5.1.
As a consequence,fpdf2
no more uses thepickle
module.
new_x/new_y, highlight annotations, text_mode & blend_mode
Added
- new parameters
new_x
andnew_y
forcell()
andmulti_cell()
, replacingln=0
, thanks to @gmischler - new
add_highlight()
method to insert highlight annotations: documentation - new
offset_rendering()
method: documentation - new
.text_mode
property: documentation - the page structure of the documentation has been revised, with a new page about adding text, thanks to @gmischler
- a warning is now raised if a context manager is used inside an
unbreakable()
section, which is not supported
Changed
local_context()
can now "scope" even more properties, likeblend_mode
: documentation
Fixed
- No font properties should be leaked anymore after using markdown or in any other situations (cf. #359), thanks to @gmischler
- If
multi_cell(align="J")
is given text with multiple paragraphs (text followed by an empty line) at once, it now renders the last line of each paragraph left-aligned,
instead of just the very last line (cf. #364), thanks to @gmischler - a regression: now again
multi_cell()
always renders a cell, even iftxt
is an empty string - cf. #349 - a bug with string width calculation when Markdown is enabled - cf. #351
- a few bugs when parsing some SVG files - cf. #356, #358 & #376
- a bug when using
multi_cell(..., split_only=True)
inside anunbreakable
section - cf. #359
Deprecated
- The parameter
ln
tocell()
andmulti_cell()
is now deprecated, usenew_x
andnew_y
instead. - The parameter
center
tocell()
is now deprecated, usealign="C"
instead.
Displaying deprecation warnings
DeprecationWarning
s are not displayed by Python by default.
Hence, every time you use a newer version of fpdf2
, we strongly encourage you to execute your scripts
with the -Wd
option (cf. documentation)
in order to get warned about deprecated features used in your code.
This can also be enabled programmatically with warnings.simplefilter('default', DeprecationWarning)
.
Support for soft-hyphens - image() can now insert .svg files - deprecating font caching
Added
- support for soft-hyphen (
\u00ad
) break inwrite()
,cell()
&multi_cell()
calls - thanks @oleksii-shyman & @gmischler!
Documentation: Line breaks - new documentation page on Emojis, Symbols & Dingbats
- documentation on combining
borb
&fpdf2
: Creating a borb.pdf.document.Document from a FPDF instance
Changed
write()
now supports soft hyphen characters, thanks to @gmischlerfname
is now a required parameter forFPDF.add_font()
image()
method now insert.svg
images as PDF paths- the defusedxml package was added as dependency in order to make SVG parsing safer
- log level of
_substitute_page_number()
has been lowered fromINFO
toDEBUG
Fixed
- a bug when rendering Markdown and setting a custom
text_color
orfill_color
- a bug in
get_string_width()
with unicode fonts and Markdown enabled,
resulting in calls tocell()
/multi_cell()
withalign="R"
to display nothing - thanks @mcerveny for the fix! - a bug with incorrect width calculation of markdown text
Deprecated
- the font caching mechanism, that used the
pickle
module, has been removed, for security reasons,
and because it provided little performance gain, and only for specific use cases - cf. issue #345.
That means that thefont_cache_dir
optional parameter offpdf.FPDF
constructor
and theuni
optional argument ofFPDF.add_font()
are deprecated.
Thefpdf.fpdf.load_cache
function has also been removed.
To be extra clear: uni=True
can now be removed from all calls to FPDF.add_font()
.
If the value of the fname
argument passed to add_font()
ends with .ttf
, it is considered a TrueType font.