From dc250c90c0158d203d34630c1139c609c1a7e38c Mon Sep 17 00:00:00 2001 From: Lucas Cimon <925560+Lucas-C@users.noreply.github.com> Date: Fri, 4 Mar 2022 20:02:49 +0100 Subject: [PATCH] Deprecating font caching mechanism + support for .pkl font files definitions - cf. #345 --- CHANGELOG.md | 8 + README.md | 1 + docs/EmojisSymbolsDingbats.md | 2 +- docs/Unicode.md | 10 +- fpdf/fpdf.py | 193 ++++++------------ test/cells/test_cell.py | 12 +- test/cells/test_multi_cell.py | 2 +- test/cells/test_multi_cell_markdown.py | 8 +- .../end_to_end_legacy/charmap/test_charmap.py | 2 +- test/fonts/add_font_from_pkl.pdf | Bin 6807 -> 0 bytes test/fonts/add_font_subset_complete.pdf | Bin 6913 -> 0 bytes test/fonts/test_add_font.py | 54 +---- test/fonts/test_font_remap.py | 10 +- test/html/test_html.py | 6 +- test/outline/test_outline.py | 2 +- test/utils/test_load_cache.py | 18 -- tutorial/unicode.py | 10 +- 17 files changed, 117 insertions(+), 221 deletions(-) delete mode 100644 test/fonts/add_font_from_pkl.pdf delete mode 100644 test/fonts/add_font_subset_complete.pdf delete mode 100644 test/utils/test_load_cache.py diff --git a/CHANGELOG.md b/CHANGELOG.md index b1e19d0f5..117adf5b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and [PEP 440](https://www.python.org/dev/peps/pep-0440/). ### Changed - `image()` method now insert `.svg` images as PDF paths +- the [defusedxml](https://pypi.org/project/defusedxml/) package was added as dependency in order to make SVG parsing safer - log level of `_substitute_page_number()` has been lowered from `INFO` to `DEBUG` ### Fixed @@ -22,6 +23,13 @@ and [PEP 440](https://www.python.org/dev/peps/pep-0440/). resulting in calls to `cell()` / `multi_cell()` with `align="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, and only for specific use cases - _cf._ [issue #345](https://github.com/PyFPDF/fpdf2/issues/345). + That means that the `font_cache_dir` optional paramater of `fpdf.FPDF` + and the `uni` optional paramater of `FPDF.add_font` are deprecated. + The `fpdf.fpdf.load_cache` function has also been removed. + ## [2.5.0] - 2022-01-22 ### Added Thanks to @torque for contributing this massive new feature: diff --git a/README.md b/README.md index 7f9e4c16d..f632bfffd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Pypi latest version](https://img.shields.io/pypi/v/fpdf2.svg)](https://pypi.python.org/pypi/fpdf2) [![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) [![codecov](https://codecov.io/gh/PyFPDF/fpdf2/branch/master/graph/badge.svg)](https://codecov.io/gh/PyFPDF/fpdf2) +[![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit) [![Downloads per month](https://pepy.tech/badge/fpdf2/month)](https://pepy.tech/project/fpdf2) [![Discussions](https://img.shields.io/github/discussions/PyFPDF/fpdf2)](https://github.com/PyFPDF/fpdf2/discussions) diff --git a/docs/EmojisSymbolsDingbats.md b/docs/EmojisSymbolsDingbats.md index ef1cb36cc..c013b106d 100644 --- a/docs/EmojisSymbolsDingbats.md +++ b/docs/EmojisSymbolsDingbats.md @@ -11,7 +11,7 @@ Here is an example using the [DejaVu](https://dejavu-fonts.github.io) font: import fpdf pdf = fpdf.FPDF() -pdf.add_font("DejaVuSans", fname="DejaVuSans.ttf", uni=True) +pdf.add_font("DejaVuSans", fname="DejaVuSans.ttf") pdf.set_font("DejaVuSans", size=64) pdf.add_page() pdf.multi_cell(0, txt="".join([chr(0x1F600 + x) for x in range(68)])) diff --git a/docs/Unicode.md b/docs/Unicode.md index 129cd17ad..762d22528 100644 --- a/docs/Unicode.md +++ b/docs/Unicode.md @@ -59,7 +59,7 @@ pdf.add_page() # Add a DejaVu Unicode font (uses UTF-8) # Supports more than 200 languages. For a coverage status see: # http://dejavu.svn.sourceforge.net/viewvc/dejavu/trunk/dejavu-fonts/langcover.txt -pdf.add_font('DejaVu', fname='DejaVuSansCondensed.ttf', uni=True) +pdf.add_font('DejaVu', fname='DejaVuSansCondensed.ttf') pdf.set_font('DejaVu', size=14) text = u""" @@ -81,14 +81,14 @@ for txt in text.split('\n'): # Supports: Bengali, Devanagari, Gujarati, # Gurmukhi (including the variants for Punjabi) # Kannada, Malayalam, Oriya, Tamil, Telugu, Tibetan -pdf.add_font('gargi', fname='gargi.ttf', uni=True) +pdf.add_font('gargi', fname='gargi.ttf') pdf.set_font('gargi', size=14) pdf.write(8, u'Hindi: नमस्ते दुनिया') pdf.ln(20) # Add a AR PL New Sung Unicode font (uses UTF-8) # The Open Source Chinese Font (also supports other east Asian languages) -pdf.add_font('fireflysung', fname='fireflysung.ttf', uni=True) +pdf.add_font('fireflysung', fname='fireflysung.ttf') pdf.set_font('fireflysung', size=14) pdf.write(8, u'Chinese: 你好世界\n') pdf.write(8, u'Japanese: こんにちは世界\n') @@ -97,13 +97,13 @@ pdf.ln(10) # Add a Alee Unicode font (uses UTF-8) # General purpose Hangul truetype fonts that contain Korean syllable # and Latin9 (iso8859-15) characters. -pdf.add_font('eunjin', fname='Eunjin.ttf', uni=True) +pdf.add_font('eunjin', fname='Eunjin.ttf') pdf.set_font('eunjin', size=14) pdf.write(8, u'Korean: 안녕하세요') pdf.ln(20) # Add a Fonts-TLWG (formerly ThaiFonts-Scalable) (uses UTF-8) -pdf.add_font('waree', fname='Waree.ttf', uni=True) +pdf.add_font('waree', fname='Waree.ttf') pdf.set_font('waree', size=14) pdf.write(8, u'Thai: สวัสดีชาวโลก') pdf.ln(20) diff --git a/fpdf/fpdf.py b/fpdf/fpdf.py index 45b3a1620..ef405b925 100644 --- a/fpdf/fpdf.py +++ b/fpdf/fpdf.py @@ -14,7 +14,6 @@ The version number is updated here (above and below in variable). """ -import errno import hashlib import io import logging @@ -202,17 +201,6 @@ def get_page_format(format, k=None): raise FPDFPageFormatException(f"Arguments must be numbers: {args}") from e -def load_cache(filename: Path): - """Return unpickled object, or None if cache unavailable""" - if not filename: - return None - try: - return pickle.loads(filename.read_bytes()) - # File missing, unsupported pickle, etc - except (OSError, ValueError): - return None - - def check_page(fn): """Decorator to protect drawing methods""" @@ -232,7 +220,11 @@ class FPDF(GraphicsStateMixin): MARKDOWN_UNDERLINE_MARKER = "--" def __init__( - self, orientation="portrait", unit="mm", format="A4", font_cache_dir=True + self, + orientation="portrait", + unit="mm", + format="A4", + font_cache_dir="DEPRECATED", ): """ Args: @@ -245,11 +237,13 @@ def __init__( Default to "mm". format (str): possible values are "a3", "a4", "a5", "letter", "legal" or a tuple (width, height) expressed in the given unit. Default to "a4". - font_cache_dir (Path or str): directory where pickle files - for TTF font files are kept. - `None` disables font chaching. - The default is `True`, meaning the current folder. + font_cache_dir (Path or str): [**DEPRECATED**] unused """ + if font_cache_dir != "DEPRECATED": + warnings.warn( + '"font_cache_dir" parameter is deprecated, unused and will soon be removed', + PendingDeprecationWarning, + ) super().__init__() # Initialization of instance attributes self.offsets = {} # array of object offsets @@ -272,7 +266,6 @@ def __init__( self.ws = 0 # word spacing self.angle = 0 # used by deprecated method: rotate() - self.font_cache_dir = font_cache_dir self.xmp_metadata = None self.image_filter = "AUTO" self.page_duration = 0 # optional pages display duration, cf. add_page() @@ -1428,13 +1421,13 @@ def solid_arc( style, ) - def add_font(self, family, style="", fname=None, uni=False): + def add_font(self, family, style="", fname=None, uni="DEPRECATED"): """ - Imports a TrueType, OpenType or Type1 font and makes it available + Imports a TrueType or OpenType font and makes it available for later calls to the `set_font()` method. - **Warning:** for Type1 and legacy fonts it is necessary to generate a font definition file first with the `MakeFont` utility. - This feature is currently deprecated in favour of TrueType Unicode font support + **Warning:** there is partial support for Type1 and legacy fonts in .pkl font definition files, + generated by the `MakeFont` utility, but this feature is getting deprecated in favour of TrueType Unicode font support (whose fonts are automatically processed with the included `ttfonts.py` module). You will find more information on the "Unicode" documentation page. @@ -1444,17 +1437,13 @@ def add_font(self, family, style="", fname=None, uni=False): style (str): font style. "B" for bold, "I" for italic. fname (str): font file name. You can specify a relative or full path. If the file is not found, it will be searched in `FPDF_FONT_DIR`. - uni (bool): if set to `True`, enable TrueType font subset embedding. - Text will then be treated as `utf8` by default. - Calling this method with uni=False is discouraged as legacy font support is complex and deprecated. - - Notes - ----- - - Due to the fact that font processing can occupy large amount of time, some data is cached. - Cache files are created in the current folder by default. - This can be controlled with the `font_cache_dir` paramater of the `FPDF` constructor. + uni (bool): [**DEPRECATED**] unused """ + if uni != "DEPRECATED": + warnings.warn( + '"uni" parameter is deprecated, unused and will soon be removed', + PendingDeprecationWarning, + ) if not fname: fname = family.replace(" ", "") + f"{style.lower()}.pkl" style = "".join(sorted(style.upper())) @@ -1468,7 +1457,7 @@ def add_font(self, family, style="", fname=None, uni=False): if fontkey in self.fonts or fontkey in self.core_fonts: warnings.warn(f"Core font or font already added '{fontkey}': doing nothing") return - if uni: + if str(fname).endswith(".ttf"): for parent in (".", FPDF_FONT_DIR): if not parent: continue @@ -1478,14 +1467,6 @@ def add_font(self, family, style="", fname=None, uni=False): else: raise FileNotFoundError(f"TTF Font file not found: {fname}") - if self.font_cache_dir is None: - cache_dir = unifilename = None - else: - cache_dir = ( - Path() if self.font_cache_dir is True else Path(self.font_cache_dir) - ) - unifilename = cache_dir / f"{ttffilename.stem}.pkl" - # include numbers in the subset! (if alias present) # ensure that alias is mapped 1-by-1 additionally (must be replaceable) sbarr = "\x00 " @@ -1493,44 +1474,34 @@ def add_font(self, family, style="", fname=None, uni=False): sbarr += "0123456789" sbarr += self.str_alias_nb_pages - font_dict = load_cache(unifilename) - if font_dict is None: - ttf = TTFontFile() - ttf.getMetrics(ttffilename) - desc = { - "Ascent": round(ttf.ascent), - "Descent": round(ttf.descent), - "CapHeight": round(ttf.capHeight), - "Flags": ttf.flags, - "FontBBox": ( - f"[{ttf.bbox[0]:.0f} {ttf.bbox[1]:.0f}" - f" {ttf.bbox[2]:.0f} {ttf.bbox[3]:.0f}]" - ), - "ItalicAngle": int(ttf.italicAngle), - "StemV": round(ttf.stemV), - "MissingWidth": round(ttf.defaultWidth), - } - - # Generate metrics .pkl file - font_dict = { - "type": "TTF", - "name": re.sub("[ ()]", "", ttf.fullName), - "desc": desc, - "up": round(ttf.underlinePosition), - "ut": round(ttf.underlineThickness), - "ttffile": ttffilename, - "fontkey": fontkey, - "unifilename": unifilename, - "originalsize": os.stat(ttffilename).st_size, - "cw": ttf.charWidths, - } - - if unifilename: - try: - unifilename.write_bytes(pickle.dumps(font_dict)) - except OSError as e: - if e.errno != errno.EACCES: - raise # Not a permission error. + ttf = TTFontFile() + ttf.getMetrics(ttffilename) + desc = { + "Ascent": round(ttf.ascent), + "Descent": round(ttf.descent), + "CapHeight": round(ttf.capHeight), + "Flags": ttf.flags, + "FontBBox": ( + f"[{ttf.bbox[0]:.0f} {ttf.bbox[1]:.0f}" + f" {ttf.bbox[2]:.0f} {ttf.bbox[3]:.0f}]" + ), + "ItalicAngle": int(ttf.italicAngle), + "StemV": round(ttf.stemV), + "MissingWidth": round(ttf.defaultWidth), + } + + # Generate metrics .pkl file + font_dict = { + "type": "TTF", + "name": re.sub("[ ()]", "", ttf.fullName), + "desc": desc, + "up": round(ttf.underlinePosition), + "ut": round(ttf.underlineThickness), + "ttffile": ttffilename, + "fontkey": fontkey, + "originalsize": os.stat(ttffilename).st_size, + "cw": ttf.charWidths, + } self.fonts[fontkey] = { "i": len(self.fonts) + 1, @@ -1543,29 +1514,21 @@ def add_font(self, family, style="", fname=None, uni=False): "ttffile": font_dict["ttffile"], "fontkey": fontkey, "subset": SubsetMap(map(ord, sbarr)), - "unifilename": unifilename, } self.font_files[fontkey] = { "length1": font_dict["originalsize"], "type": "TTF", "ttffile": ttffilename, } - self.font_files[fname] = {"type": "TTF"} else: - if fname.endswith(".ttf"): - warnings.warn( - "When providing a TTF font file you must pass uni=True to FPDF.add_font" - ) + warnings.warn( + "Support for .pkl font files definition is deprecated, and will be removed from fpdf2 soon." + " If you require this feature, please report your need on fpdf2 GitHub project.", + PendingDeprecationWarning, + ) font_dict = pickle.loads(Path(fname).read_bytes()) - if font_dict["type"] == "TTF": - warnings.warn( - "Pickle was generated from TTF font file, setting uni=True" - ) - self.add_font(family, style=style, fname=fname, uni=True) - return - - self.fonts[fontkey] = {"i": len(self.fonts) + 1} - self.fonts[fontkey].update(font_dict) + font_dict["i"] = len(self.fonts) + 1 + self.fonts[fontkey] = font_dict diff = font_dict.get("diff") if diff: # Search existing encodings @@ -2722,7 +2685,7 @@ def image( """ if type: warnings.warn( - '"type" is unused and will soon be deprecated', + '"type" parameter is deprecated, unused and will soon be removed', PendingDeprecationWarning, ) if str(name).endswith(".svg"): @@ -3010,7 +2973,7 @@ def output(self, name="", dest=""): """ if dest: warnings.warn( - '"dest" is unused and will soon be deprecated', + '"dest" parameter is deprecated, unused and will soon be removed', PendingDeprecationWarning, ) # Finish document if necessary: @@ -3438,40 +3401,18 @@ def _putfonts(self): self.mtd(font) def _putTTfontwidths(self, font, maxUni): - if font["unifilename"] is None: - cw127fname = None - else: - cw127fname = Path(font["unifilename"]).with_suffix(".cw127.pkl") - font_dict = load_cache(cw127fname) - if font_dict: - rangeid = font_dict["rangeid"] - range_ = font_dict["range"] - prevcid = font_dict["prevcid"] - prevwidth = font_dict["prevwidth"] - interval = font_dict["interval"] - range_interval = font_dict["range_interval"] - startcid = 128 - else: - rangeid = 0 - range_ = {} - range_interval = {} - prevcid = -2 - prevwidth = -1 - interval = False - startcid = 1 + rangeid = 0 + range_ = {} + range_interval = {} + prevcid = -2 + prevwidth = -1 + interval = False + startcid = 1 cwlen = maxUni + 1 # for each character subset = font["subset"].dict() for cid in range(startcid, cwlen): - if cid == 128 and font_dict: - try: - with cw127fname.open("wb") as fh: - pickle.dump(font_dict, fh) - except OSError as e: - if e.errno != errno.EACCES: - raise # Not a permission error. - width = _char_width(font, cid) if "dw" not in font or (font["dw"] and width != font["dw"]): cid_mapped = subset.get(cid) @@ -4194,4 +4135,4 @@ def _is_xml(img: io.BytesIO): sys.modules[__name__].__class__ = WarnOnDeprecatedModuleAttributes -__all__ = ["FPDF", "load_cache", "get_page_format", "TitleStyle", "PAGE_FORMATS"] +__all__ = ["FPDF", "get_page_format", "TitleStyle", "PAGE_FORMATS"] diff --git a/test/cells/test_cell.py b/test/cells/test_cell.py index caec5426b..58e7a0b98 100644 --- a/test/cells/test_cell.py +++ b/test/cells/test_cell.py @@ -177,9 +177,9 @@ def test_cell_markdown(tmp_path): def test_cell_markdown_with_ttf_fonts(tmp_path): pdf = fpdf.FPDF() pdf.add_page() - pdf.add_font("Roboto", "", HERE / "../fonts/Roboto-Regular.ttf", uni=True) - pdf.add_font("Roboto", "B", HERE / "../fonts/Roboto-Bold.ttf", uni=True) - pdf.add_font("Roboto", "I", HERE / "../fonts/Roboto-Italic.ttf", uni=True) + pdf.add_font("Roboto", "", HERE / "../fonts/Roboto-Regular.ttf") + pdf.add_font("Roboto", "B", HERE / "../fonts/Roboto-Bold.ttf") + pdf.add_font("Roboto", "I", HERE / "../fonts/Roboto-Italic.ttf") pdf.set_font("Roboto", size=60) pdf.cell(txt="**Lorem** __Ipsum__ --dolor--", markdown=True) assert_pdf_equal(pdf, HERE / "cell_markdown_with_ttf_fonts.pdf", tmp_path) @@ -188,7 +188,7 @@ def test_cell_markdown_with_ttf_fonts(tmp_path): def test_cell_markdown_missing_ttf_font(tmp_path): pdf = fpdf.FPDF() pdf.add_page() - pdf.add_font("Roboto", fname=HERE / "../fonts/Roboto-Regular.ttf", uni=True) + pdf.add_font("Roboto", fname=HERE / "../fonts/Roboto-Regular.ttf") pdf.set_font("Roboto", size=60) with pytest.raises(fpdf.FPDFException) as error: pdf.cell(txt="**Lorem Ipsum**", markdown=True) @@ -214,8 +214,8 @@ def test_cell_markdown_bleeding(tmp_path): # issue 241 def test_cell_markdown_right_aligned(tmp_path): # issue 333 pdf = fpdf.FPDF() pdf.add_page() - pdf.add_font("Roboto", "", HERE / "../fonts/Roboto-Regular.ttf", uni=True) - pdf.add_font("Roboto", "B", HERE / "../fonts/Roboto-Bold.ttf", uni=True) + pdf.add_font("Roboto", "", HERE / "../fonts/Roboto-Regular.ttf") + pdf.add_font("Roboto", "B", HERE / "../fonts/Roboto-Bold.ttf") pdf.set_font("Roboto", size=60) pdf.cell( 0, diff --git a/test/cells/test_multi_cell.py b/test/cells/test_multi_cell.py index 8eb5fb4a3..7c0e7687b 100644 --- a/test/cells/test_multi_cell.py +++ b/test/cells/test_multi_cell.py @@ -163,7 +163,7 @@ def test_multi_cell_table_unbreakable(tmp_path): # issue 111 def test_multi_cell_justified_with_unicode_font(tmp_path): # issue 118 pdf = fpdf.FPDF() pdf.add_page() - pdf.add_font("DejaVu", "", HERE / "../fonts/DejaVuSans.ttf", uni=True) + pdf.add_font("DejaVu", "", HERE / "../fonts/DejaVuSans.ttf") pdf.set_font("DejaVu", "", 14) text = 'Justified line containing "()" that is long enough to trigger wrapping and a line jump' pdf.multi_cell(w=0, h=8, txt=text, ln=1) diff --git a/test/cells/test_multi_cell_markdown.py b/test/cells/test_multi_cell_markdown.py index cb0245659..cd7a8d70f 100644 --- a/test/cells/test_multi_cell_markdown.py +++ b/test/cells/test_multi_cell_markdown.py @@ -27,9 +27,9 @@ def test_multi_cell_markdown(tmp_path): def test_multi_cell_markdown_with_ttf_fonts(tmp_path): pdf = fpdf.FPDF() pdf.add_page() - pdf.add_font("Roboto", "", HERE / "../fonts/Roboto-Regular.ttf", uni=True) - pdf.add_font("Roboto", "B", HERE / "../fonts/Roboto-Bold.ttf", uni=True) - pdf.add_font("Roboto", "I", HERE / "../fonts/Roboto-Italic.ttf", uni=True) + pdf.add_font("Roboto", "", HERE / "../fonts/Roboto-Regular.ttf") + pdf.add_font("Roboto", "B", HERE / "../fonts/Roboto-Bold.ttf") + pdf.add_font("Roboto", "I", HERE / "../fonts/Roboto-Italic.ttf") pdf.set_font("Roboto", size=32) text = ( # Some text where styling occur over line breaks: "Lorem ipsum dolor, **consectetur adipiscing** elit," @@ -46,7 +46,7 @@ def test_multi_cell_markdown_with_ttf_fonts(tmp_path): def test_multi_cell_markdown_missing_ttf_font(): pdf = fpdf.FPDF() pdf.add_page() - pdf.add_font("Roboto", fname=HERE / "../fonts/Roboto-Regular.ttf", uni=True) + pdf.add_font("Roboto", fname=HERE / "../fonts/Roboto-Regular.ttf") pdf.set_font("Roboto", size=60) with pytest.raises(fpdf.FPDFException) as error: pdf.multi_cell(w=pdf.epw, txt="**Lorem Ipsum**", markdown=True) diff --git a/test/end_to_end_legacy/charmap/test_charmap.py b/test/end_to_end_legacy/charmap/test_charmap.py index 4ddfcd252..329676107 100644 --- a/test/end_to_end_legacy/charmap/test_charmap.py +++ b/test/end_to_end_legacy/charmap/test_charmap.py @@ -48,7 +48,7 @@ def test_first_999_chars(font_filename, tmp_path): pdf = fpdf.FPDF() pdf.add_page() - pdf.add_font(font_name, fname=font_path, uni=True) + pdf.add_font(font_name, fname=font_path) pdf.set_font(font_name, size=10) ttf = MyTTFontFile() diff --git a/test/fonts/add_font_from_pkl.pdf b/test/fonts/add_font_from_pkl.pdf deleted file mode 100644 index 2f136aafea4ee599bb265d39b78ae38be652695f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6807 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 diff --git a/test/fonts/add_font_subset_complete.pdf b/test/fonts/add_font_subset_complete.pdf deleted file mode 100644 index 86ef1c4bd1a5ab53e511e9a23f5fa17381b939d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6913 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 puocvjLILSXW+4XxWtJ~sJC diff --git a/test/fonts/test_add_font.py b/test/fonts/test_add_font.py index 5257a2709..146e88d27 100644 --- a/test/fonts/test_add_font.py +++ b/test/fonts/test_add_font.py @@ -10,20 +10,13 @@ HERE = Path(__file__).resolve().parent -def test_add_font_non_existing_file(): +def test_add_font_non_existing(): pdf = FPDF() - with pytest.raises(FileNotFoundError) as error: - pdf.add_font("non-existing") - expected_msg = "[Errno 2] No such file or directory: 'non-existing.pkl'" - assert str(error.value) == expected_msg - - -def test_add_font_non_existing_file_unicode(): - pdf = FPDF() - with pytest.raises(FileNotFoundError) as error: - pdf.add_font("non-existing", uni=True) - expected_msg = "TTF Font file not found: non-existing.pkl" - assert str(error.value) == expected_msg + for uni in (True, False): + with pytest.raises(FileNotFoundError) as error: + pdf.add_font("non-existing", uni=uni) + expected_msg = "[Errno 2] No such file or directory: 'non-existing.pkl'" + assert str(error.value) == expected_msg def test_deprecation_warning_for_FPDF_CACHE_DIR(): @@ -61,7 +54,7 @@ def test_add_font_unicode_with_path_fname_ok(tmp_path): for font_cache_dir in (True, tmp_path, None): pdf = FPDF(font_cache_dir=font_cache_dir) font_file_path = HERE / "Roboto-Regular.ttf" - pdf.add_font("Roboto-Regular", fname=str(font_file_path), uni=True) + pdf.add_font("Roboto-Regular", fname=str(font_file_path)) pdf.set_font("Roboto-Regular", size=64) pdf.add_page() pdf.cell(txt="Hello World!") @@ -72,42 +65,13 @@ def test_add_font_unicode_with_str_fname_ok(tmp_path): for font_cache_dir in (True, str(tmp_path), None): pdf = FPDF(font_cache_dir=font_cache_dir) font_file_path = HERE / "Roboto-Regular.ttf" - pdf.add_font("Roboto-Regular", fname=str(font_file_path), uni=True) + pdf.add_font("Roboto-Regular", fname=str(font_file_path)) pdf.set_font("Roboto-Regular", size=64) pdf.add_page() pdf.cell(txt="Hello World!") assert_pdf_equal(pdf, HERE / "add_font_unicode.pdf", tmp_path) -def test_add_font_from_pkl(tmp_path): - pdf = FPDF() - font_file_path = HERE / "Roboto-Regular.ttf" - pdf.add_font("Roboto-Regular", fname=str(font_file_path), uni=True) - del pdf.fonts["roboto-regular"] # required to be allow to re-add it - # re-using .pkl file generated by previous method call: - pdf.add_font("Roboto-Regular") - pdf.set_font("Roboto-Regular", size=64) - pdf.add_page() - pdf.cell(txt="Hello World!") - assert_pdf_equal(pdf, HERE / "add_font_from_pkl.pdf", tmp_path) - - -def test_add_font_subset_complete(tmp_path): - pdf = FPDF() - pdf.alias_nb_pages(None) - - font_file_path = HERE / "Roboto-Regular.ttf" - pdf.add_font("Roboto-Regular", fname=str(font_file_path), uni=True) - - pdf = FPDF() - # re-using .pkl file generated by previous instance - pdf.add_font("Roboto-Regular") - pdf.set_font("Roboto-Regular", size=64) - pdf.add_page() - pdf.cell(txt="This is page {nb}") - assert_pdf_equal(pdf, HERE / "add_font_subset_complete.pdf", tmp_path) - - def teardown(): # Clean-up for test_add_font_from_pkl with suppress(FileNotFoundError): @@ -130,7 +94,7 @@ def test_add_core_fonts(): def test_render_en_dash(tmp_path): # issue-166 pdf = FPDF() font_file_path = HERE / "Roboto-Regular.ttf" - pdf.add_font("Roboto-Regular", fname=str(font_file_path), uni=True) + pdf.add_font("Roboto-Regular", fname=str(font_file_path)) pdf.set_font("Roboto-Regular", size=120) pdf.add_page() pdf.cell(w=pdf.epw, txt="–") # U+2013 diff --git a/test/fonts/test_font_remap.py b/test/fonts/test_font_remap.py index 2712f69ee..f7e9d1822 100644 --- a/test/fonts/test_font_remap.py +++ b/test/fonts/test_font_remap.py @@ -37,7 +37,7 @@ def test_emoji_glyph(tmp_path): pdf = FPDF(font_cache_dir=tmp_path) font_file_path = HERE / "DejaVuSans.ttf" - pdf.add_font("DejaVuSans", fname=str(font_file_path), uni=True) + pdf.add_font("DejaVuSans", fname=str(font_file_path)) pdf.set_font("DejaVuSans", size=64) pdf.add_page() @@ -53,7 +53,7 @@ def test_nb_replace(tmp_path): pdf = FPDF(font_cache_dir=tmp_path) font_file_path = HERE / "DejaVuSans.ttf" - pdf.add_font("DejaVuSans", fname=str(font_file_path), uni=True) + pdf.add_font("DejaVuSans", fname=str(font_file_path)) pdf.add_page() pdf.set_font("DejaVuSans", size=64) @@ -70,8 +70,8 @@ def test_two_mappings(tmp_path): font_file_path_1 = HERE / "DejaVuSans.ttf" font_file_path_2 = HERE / "DroidSansFallback.ttf" - pdf.add_font("DejaVuSans", fname=str(font_file_path_1), uni=True) - pdf.add_font("DroidSansFallback", fname=str(font_file_path_2), uni=True) + pdf.add_font("DejaVuSans", fname=str(font_file_path_1)) + pdf.add_font("DroidSansFallback", fname=str(font_file_path_2)) pdf.add_page() pdf.set_font("DejaVuSans", size=64) @@ -85,7 +85,7 @@ def test_two_mappings(tmp_path): def test_thai_text(tmp_path): pdf = FPDF(font_cache_dir=tmp_path) - pdf.add_font("Waree", fname=HERE / "Waree.ttf", uni=True) + pdf.add_font("Waree", fname=HERE / "Waree.ttf") pdf.set_font("Waree") pdf.add_page() pdf.write(txt="สวัสดีชาวโลก ทดสอบฟอนต์, Hello world font test.") diff --git a/test/html/test_html.py b/test/html/test_html.py index 735e1cb43..4bc42ba10 100644 --- a/test/html/test_html.py +++ b/test/html/test_html.py @@ -402,7 +402,7 @@ def test_html_justify_paragraph(tmp_path): def test_issue_156(tmp_path): pdf = MyFPDF() - pdf.add_font("Roboto", style="B", fname="test/fonts/Roboto-Bold.ttf", uni=True) + pdf.add_font("Roboto", style="B", fname="test/fonts/Roboto-Bold.ttf") pdf.set_font("Roboto", style="B") pdf.add_page() with pytest.raises(FPDFException) as error: @@ -411,7 +411,7 @@ def test_issue_156(tmp_path): str(error.value) == "Undefined font: roboto - Use built-in fonts or FPDF.add_font() beforehand" ) - pdf.add_font("Roboto", fname="test/fonts/Roboto-Regular.ttf", uni=True) + pdf.add_font("Roboto", fname="test/fonts/Roboto-Regular.ttf") pdf.write_html("Regular text
Bold text") assert_pdf_equal(pdf, HERE / "issue_156.pdf", tmp_path) @@ -432,7 +432,7 @@ def test_html_font_color_name(tmp_path): def test_html_heading_hebrew(tmp_path): pdf = MyFPDF() - pdf.add_font("DejaVuSans", fname=HERE / "../fonts/DejaVuSans.ttf", uni=True) + pdf.add_font("DejaVuSans", fname=HERE / "../fonts/DejaVuSans.ttf") pdf.set_font("DejaVuSans") pdf.add_page() pdf.write_html("

Hebrew: שלום עולם

") diff --git a/test/outline/test_outline.py b/test/outline/test_outline.py index 31a8057d4..316887759 100644 --- a/test/outline/test_outline.py +++ b/test/outline/test_outline.py @@ -161,7 +161,7 @@ def test_2_pages_outline(tmp_path): def test_russian_heading(tmp_path): # issue-320 pdf = FPDF() - pdf.add_font("Roboto", style="B", fname="test/fonts/Roboto-Regular.ttf", uni=True) + pdf.add_font("Roboto", style="B", fname="test/fonts/Roboto-Regular.ttf") pdf.set_font("Roboto", style="B") pdf.add_page() pdf.start_section("Русский, English, 1 2 3...") diff --git a/test/utils/test_load_cache.py b/test/utils/test_load_cache.py deleted file mode 100644 index c2e5923bf..000000000 --- a/test/utils/test_load_cache.py +++ /dev/null @@ -1,18 +0,0 @@ -import pickle - -import fpdf - - -def test_load_cache_none(): - result = fpdf.fpdf.load_cache(None) - assert result is None - - -def test_load_cache_pickle(tmp_path): - path = tmp_path / "filename.pickle" - a = {"hello": "world"} - with path.open("wb") as handle: - pickle.dump(a, handle, protocol=pickle.HIGHEST_PROTOCOL) - - assert fpdf.fpdf.load_cache(path) == a - assert fpdf.fpdf.load_cache(path.with_name("filename1.pickle")) is None diff --git a/tutorial/unicode.py b/tutorial/unicode.py index ad6ca06fd..99d0bf6d1 100644 --- a/tutorial/unicode.py +++ b/tutorial/unicode.py @@ -8,7 +8,7 @@ # Add a DejaVu Unicode font (uses UTF-8) # Supports more than 200 languages. For a coverage status see: # http://dejavu.svn.sourceforge.net/viewvc/dejavu/trunk/dejavu-fonts/langcover.txt -pdf.add_font("DejaVu", fname="DejaVuSansCondensed.ttf", uni=True) +pdf.add_font("DejaVu", fname="DejaVuSansCondensed.ttf") pdf.set_font("DejaVu", size=14) text = """ @@ -30,14 +30,14 @@ # Supports: Bengali, Devanagari, Gujarati, # Gurmukhi (including the variants for Punjabi) # Kannada, Malayalam, Oriya, Tamil, Telugu, Tibetan -pdf.add_font("gargi", fname="gargi.ttf", uni=True) +pdf.add_font("gargi", fname="gargi.ttf") pdf.set_font("gargi", size=14) pdf.write(8, "Hindi: नमस्ते दुनिया") pdf.ln(20) # Add a AR PL New Sung Unicode font (uses UTF-8) # The Open Source Chinese Font (also supports other east Asian languages) -pdf.add_font("fireflysung", fname="fireflysung.ttf", uni=True) +pdf.add_font("fireflysung", fname="fireflysung.ttf") pdf.set_font("fireflysung", size=14) pdf.write(8, "Chinese: 你好世界\n") pdf.write(8, "Japanese: こんにちは世界\n") @@ -46,13 +46,13 @@ # Add a Alee Unicode font (uses UTF-8) # General purpose Hangul truetype fonts that contain Korean syllable # and Latin9 (iso8859-15) characters. -pdf.add_font("eunjin", fname="Eunjin.ttf", uni=True) +pdf.add_font("eunjin", fname="Eunjin.ttf") pdf.set_font("eunjin", size=14) pdf.write(8, "Korean: 안녕하세요") pdf.ln(20) # Add a Fonts-TLWG (formerly ThaiFonts-Scalable) (uses UTF-8) -pdf.add_font("waree", fname="Waree.ttf", uni=True) +pdf.add_font("waree", fname="Waree.ttf") pdf.set_font("waree", size=14) pdf.write(8, "Thai: สวัสดีชาวโลก") pdf.ln(20)