From 606b5ae1e53f5e2e26977c293747e6291283b2b9 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 17 Oct 2021 23:29:41 +0300 Subject: [PATCH 1/3] Remove support for FreeType 2.7 and older --- Tests/test_imagefont.py | 23 +---------------------- Tests/test_imagefontctl.py | 22 ++-------------------- docs/deprecations.rst | 26 +++++++++++++------------- docs/releasenotes/9.0.0.rst | 25 ++++++++++++++++++++++--- docs/releasenotes/template.rst | 3 +++ src/PIL/ImageFont.py | 20 +------------------- src/_imagingft.c | 4 ---- 7 files changed, 42 insertions(+), 81 deletions(-) diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index 6f7646cb0..cb1f45ca2 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -757,11 +757,7 @@ class TestImageFont: name, text = "quick", "Quick" path = f"Tests/images/test_anchor_{name}_{anchor}.png" - freetype = parse_version(features.version_module("freetype2")) - if freetype < parse_version("2.4"): - width, height = (129, 44) - left = left_old - elif self.LAYOUT_ENGINE == ImageFont.LAYOUT_RAQM: + if self.LAYOUT_ENGINE == ImageFont.LAYOUT_RAQM: width, height = (129, 44) else: width, height = (128, 44) @@ -894,7 +890,6 @@ class TestImageFont: assert_image_similar_tofile(im, "Tests/images/standard_embedded.png", 6.2) - @skip_unless_feature_version("freetype2", "2.5.0") def test_cbdt(self): try: font = ImageFont.truetype( @@ -913,7 +908,6 @@ class TestImageFont: assert str(e) in ("unimplemented feature", "unknown file format") pytest.skip("freetype compiled without libpng or CBDT support") - @skip_unless_feature_version("freetype2", "2.5.0") def test_cbdt_mask(self): try: font = ImageFont.truetype( @@ -934,7 +928,6 @@ class TestImageFont: assert str(e) in ("unimplemented feature", "unknown file format") pytest.skip("freetype compiled without libpng or CBDT support") - @skip_unless_feature_version("freetype2", "2.5.1") def test_sbix(self): try: font = ImageFont.truetype( @@ -953,7 +946,6 @@ class TestImageFont: assert str(e) in ("unimplemented feature", "unknown file format") pytest.skip("freetype compiled without libpng or SBIX support") - @skip_unless_feature_version("freetype2", "2.5.1") def test_sbix_mask(self): try: font = ImageFont.truetype( @@ -1008,7 +1000,6 @@ class TestImageFont_RaqmLayout(TestImageFont): LAYOUT_ENGINE = ImageFont.LAYOUT_RAQM -@skip_unless_feature_version("freetype2", "2.4", "Different metrics") def test_render_mono_size(): # issue 4177 @@ -1024,18 +1015,6 @@ def test_render_mono_size(): assert_image_equal_tofile(im, "Tests/images/text_mono.gif") -def test_freetype_deprecation(monkeypatch): - # Arrange: mock features.version_module to return fake FreeType version - def fake_version_module(module): - return "2.7" - - monkeypatch.setattr(features, "version_module", fake_version_module) - - # Act / Assert - with pytest.warns(DeprecationWarning): - ImageFont.truetype(FONT_PATH, FONT_SIZE) - - @pytest.mark.parametrize( "test_file", [ diff --git a/Tests/test_imagefontctl.py b/Tests/test_imagefontctl.py index f2a914ff7..ffb70cf17 100644 --- a/Tests/test_imagefontctl.py +++ b/Tests/test_imagefontctl.py @@ -1,13 +1,8 @@ import pytest -from packaging.version import parse as parse_version -from PIL import Image, ImageDraw, ImageFont, features +from PIL import Image, ImageDraw, ImageFont -from .helper import ( - assert_image_similar_tofile, - skip_unless_feature, - skip_unless_feature_version, -) +from .helper import assert_image_similar_tofile, skip_unless_feature FONT_SIZE = 20 FONT_PATH = "Tests/fonts/DejaVuSans/DejaVuSans.ttf" @@ -252,11 +247,6 @@ def test_getlength_combine(mode, direction, text): pytest.skip("libraqm 0.7 or greater not available") -# FreeType 2.5.1 README: Miscellaneous Changes: -# Improved computation of emulated vertical metrics for TrueType fonts. -@skip_unless_feature_version( - "freetype2", "2.5.1", "FreeType <2.5.1 has incompatible ttb metrics" -) @pytest.mark.parametrize("anchor", ("lt", "mm", "rb", "sm")) def test_anchor_ttb(anchor): text = "f" @@ -315,14 +305,6 @@ combine_tests = ( "name, text, anchor, dir, epsilon", combine_tests, ids=[r[0] for r in combine_tests] ) def test_combine(name, text, dir, anchor, epsilon): - if ( - parse_version(features.version_module("freetype2")) < parse_version("2.5.1") - and dir == "ttb" - ): - # FreeType 2.5.1 README: Miscellaneous Changes: - # Improved computation of emulated vertical metrics for TrueType fonts. - pytest.skip("FreeType <2.5.1 has incompatible ttb metrics") - path = f"Tests/images/test_combine_{name}.png" f = ImageFont.truetype("Tests/fonts/NotoSans-Regular.ttf", 48) diff --git a/docs/deprecations.rst b/docs/deprecations.rst index 7318da5b7..077f78ef5 100644 --- a/docs/deprecations.rst +++ b/docs/deprecations.rst @@ -12,19 +12,6 @@ Deprecated features Below are features which are considered deprecated. Where appropriate, a ``DeprecationWarning`` is issued. -FreeType 2.7 -~~~~~~~~~~~~ - -.. deprecated:: 8.1.0 - -Support for FreeType 2.7 is deprecated and will be removed in Pillow 9.0.0 (2022-01-02), -when FreeType 2.8 will be the minimum supported. - -We recommend upgrading to at least FreeType `2.10.4`_, which fixed a severe -vulnerability introduced in FreeType 2.6 (:cve:`CVE-2020-15999`). - -.. _2.10.4: https://sourceforge.net/projects/freetype/files/freetype2/2.10.4/ - Tk/Tcl 8.4 ~~~~~~~~~~ @@ -111,6 +98,19 @@ ImageFile.raise_ioerror So, ``ImageFile.raise_ioerror`` has been removed. Use ``ImageFile.raise_oserror`` instead. +FreeType 2.7 +~~~~~~~~~~~~ + +.. deprecated:: 8.1.0 +.. versionremoved:: 9.0.0 + +Support for FreeType 2.7 has been removed. + +We recommend upgrading to at least `FreeType`_ 2.10.4, which fixed a severe +vulnerability introduced in FreeType 2.6 (:cve:`CVE-2020-15999`). + +.. _FreeType: https://www.freetype.org + im.offset ~~~~~~~~~ diff --git a/docs/releasenotes/9.0.0.rst b/docs/releasenotes/9.0.0.rst index 9991655e7..6965b65bf 100644 --- a/docs/releasenotes/9.0.0.rst +++ b/docs/releasenotes/9.0.0.rst @@ -9,25 +9,44 @@ PILLOW_VERSION constant ``PILLOW_VERSION`` has been removed. Use ``__version__`` instead. +FreeType 2.7 +^^^^^^^^^^^^ + +Support for FreeType 2.7 has been removed; FreeType 2.8 is the minimum supported. + +We recommend upgrading to at least `FreeType`_ 2.10.4, which fixed a severe +vulnerability introduced in FreeType 2.6 (:cve:`CVE-2020-15999`). + +.. _FreeType: https://www.freetype.org + Image.show command parameter -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ``command`` parameter has been removed. Use a subclass of :py:class:`PIL.ImageShow.Viewer` instead. Image._showxv -~~~~~~~~~~~~~ +^^^^^^^^^^^^^ ``Image._showxv`` has been removed. Use :py:meth:`~PIL.Image.Image.show` instead. If custom behaviour is required, use :py:meth:`~PIL.ImageShow.register` to add a custom :py:class:`~PIL.ImageShow.Viewer` class. ImageFile.raise_ioerror -~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^ ``IOError`` was merged into ``OSError`` in Python 3.3. So, ``ImageFile.raise_ioerror`` has been removed. Use ``ImageFile.raise_oserror`` instead. + +Deprecations +============ + +TODO +^^^^ + +TODO + API Changes =========== diff --git a/docs/releasenotes/template.rst b/docs/releasenotes/template.rst index bf381114e..f7271ae2b 100644 --- a/docs/releasenotes/template.rst +++ b/docs/releasenotes/template.rst @@ -34,6 +34,9 @@ TODO Security ======== +TODO +^^^^ + TODO Other Changes diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index e99ca21b2..a212110a8 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -28,10 +28,9 @@ import base64 import os import sys -import warnings from io import BytesIO -from . import Image, features +from . import Image from ._util import isDirectory, isPath LAYOUT_BASIC = 0 @@ -165,23 +164,6 @@ class FreeTypeFont: self.index = index self.encoding = encoding - try: - from packaging.version import parse as parse_version - except ImportError: - pass - else: - freetype_version = features.version_module("freetype2") - if freetype_version is not None and parse_version( - freetype_version - ) < parse_version("2.8"): - warnings.warn( - "Support for FreeType 2.7 is deprecated and will be removed" - " in Pillow 9 (2022-01-02). Please upgrade to FreeType 2.8 " - "or newer, preferably FreeType 2.10.4 which fixes " - "CVE-2020-15999.", - DeprecationWarning, - ) - if layout_engine not in (LAYOUT_BASIC, LAYOUT_RAQM): layout_engine = LAYOUT_BASIC if core.HAVE_RAQM: diff --git a/src/_imagingft.c b/src/_imagingft.c index bbfca187e..8f19b763c 100644 --- a/src/_imagingft.c +++ b/src/_imagingft.c @@ -933,11 +933,7 @@ font_render(FontObject *self, PyObject *args) { case FT_PIXEL_MODE_GRAY2: case FT_PIXEL_MODE_GRAY4: if (!bitmap_converted_ready) { -#if FREETYPE_MAJOR > 2 || (FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 6) FT_Bitmap_Init(&bitmap_converted); -#else - FT_Bitmap_New(&bitmap_converted); -#endif bitmap_converted_ready = 1; } error = FT_Bitmap_Convert(library, &bitmap, &bitmap_converted, 1); From cb5c8f6f869b6ea2306b860f5096e9e36cff3f1d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 18 Oct 2021 11:28:14 +0300 Subject: [PATCH 2/3] Remove unused left_old variable --- Tests/test_imagefont.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index cb1f45ca2..acc1cdb13 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -738,22 +738,22 @@ class TestImageFont: d.textbbox((0, 0), "test", font=default_font) @pytest.mark.parametrize( - "anchor, left, left_old, top", + "anchor, left, top", ( # test horizontal anchors - ("ls", 0, 0, -36), - ("ms", -64, -65, -36), - ("rs", -128, -129, -36), + ("ls", 0, -36), + ("ms", -64, -36), + ("rs", -128, -36), # test vertical anchors - ("ma", -64, -65, 16), - ("mt", -64, -65, 0), - ("mm", -64, -65, -17), - ("mb", -64, -65, -44), - ("md", -64, -65, -51), + ("ma", -64, 16), + ("mt", -64, 0), + ("mm", -64, -17), + ("mb", -64, -44), + ("md", -64, -51), ), ids=("ls", "ms", "rs", "ma", "mt", "mm", "mb", "md"), ) - def test_anchor(self, anchor, left, left_old, top): + def test_anchor(self, anchor, left, top): name, text = "quick", "Quick" path = f"Tests/images/test_anchor_{name}_{anchor}.png" From e6ffeac66f35ff011c59e5698d68a534a4b7ac28 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 19 Oct 2021 16:08:23 +1100 Subject: [PATCH 3/3] Updated image comparison --- Tests/images/multiline_text.png | Bin 2843 -> 3197 bytes Tests/images/multiline_text_center.png | Bin 2845 -> 3203 bytes Tests/images/multiline_text_right.png | Bin 2846 -> 3200 bytes Tests/images/multiline_text_spacing.png | Bin 2840 -> 3197 bytes Tests/test_imagefont.py | 10 +++------- 5 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Tests/images/multiline_text.png b/Tests/images/multiline_text.png index ff1308c5ef277048d26abec36dd76610e8fbf3fe..e39c6586ca507b48ddcf0091d682d7a5dcd43bee 100644 GIT binary patch delta 3125 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 JRRzEK;6I`8ReS&d literal 2843 zcmb_e_g9ly6Go6;R1lFa$^ueXno=akEJ(nFq7Vd;E+AD5MOtt*f)N8sQ33%Ll=ji2 z1?g?0OGpS(gwP2HBF&JH2r;m)>)CVm5BPqWcg~sn-g#!`nVE}ru(K8ykrUzJ;Ssli zSYGAfIiwBfenPx}Z1Bx}$-^T;v$4G7bPu;N6AZZ)t|0i8OxC&aNvC4;Pw)WoimQ{K zmCph1FPfrpQdn^tkta27dfOOjezlCq=Z2c8xeJ=AT0PnWw~NGIFz{;rrH7;IqU*X> z4rtxG%9LeRNI@i*gY?+IG1g;|E4YjK8>B=jG~ky6dR#m2lw+(l4w;kv$lqYkr3mxojpE535cqs$C{#9w4t%FoAwJzA*gcf%f!U> z&5wAzG5D{cp`q5OwH%|my1FhT_cW@psp-SGB{luJ_G}BH?DDH~Sg2ZNMQ0~+yym7) zT~4SM$F=#@tA|G)uxIDdLMkOCCF=GCViFQ8I^6~W2@DC**3g*8_fsgf6&0=>aXU-> znZJR-`uh5&W@b{7k`n?~D;ir`Of)nebF{Hg)|W9YEcCLc7z`wdeqB{n1z-2xq@)X1KqNC)_Omg{0VPkZx6b=^tf{8!iKt*R%LztRn6?XQ;?Ej>vW}vJa5Tf<-XO_ zrt)%)vuFG9FdLix`db4N1Ys$)#>PfyfjQRocq$<(D(YG(G@?nVjC)cnIVb1jl=?dY zA!4rH=jZP`3w^ z&*CGN)|0jI+LfiH36F%gF=u3f*n^r(b#y{^w?AEeRaaX}=^!ewuerM?u-08?xi`YY zx7yp=X*8c`3^hbTOl%47TJMLB-{JZ0Vd(M{hr_kDwk|C#{qe^sEcAq|EEbEc7z>io zzTO@0tIV0EPR(-Xi z)V{FBLF0wajp&8mN6E=#Tid9p9ro57OfA!{%nY#%wX{Ud zScr;<5Q)Ugo_PB@*MP*qKh z(j4-ip7~dJ`6=bB7CUJM2M2TZ_K^GEsbgbNo6{{enQHXOlVSpRMt662adC02XO|r2 zT~^ldFoX9k7aoi@gw3=T6{$>V0hzQjG0)XawpQhLlT9}=k{rvet(8VLl z7VWVNe?Pz1?z-uZAHR*>kYk@5#)*O<2n1uYDOg&>DlBZX%)T&Z&d=Z9|4U@+TuefD zqEf-?>1iLpW%A0KbVGLo)zadK$rRA&G8@81i|WAE-US3{@p zEp8NmcD%g2Z-aUH_&6L6)hZWp$w2s#sl_SPBmI#r@$4{1N5?yN-T-7sOBNofH zq=SN^!((FvygKgfDSdO(K<0bF!^u#Y`*ai_BL2~ShsykH+&h1=njhHF_am3j?|!47 zVK}my(`fHD)6FQgRECy9u)xEf2tJqe@pNU-WyiGOck}N1Xg!&q#%p#*1l1O{l)!fi zJR4SAE|eZFMEMG54(a|h^LdydDv7oyx=IZM20}X*q zTUuH=I_l(-PC8H~XTND|WCE+Or>Dol!a`VB7=yv^^Ye#Ae!lP%9MV1JAU8hU$sM-LoL=(5~grVjnU zyBPPj50k}4eEaI%-G)vqY=Z6W)>%1}`#)B9foTucul4j7cnF?PK-c zUffi<=*Q3OE9K_$#N2$=8K+qa@Dzy!p^u|2N#QW-IO1F&Nv&u^O#1wUVyar|BYm?J zS+MpAK>>kIBsUjkvn=V?g(5Z-RZ(w)z@NBG7ArX=g#ibIucU-;lUwLkT!gTZaK8V4 zBA-?%h2?!59c}a{%gx?-u>R5^);P<^Y{R;|y%6Z~D=&5F@DtL~0Bpv5&qH7YK6`dl zS-G$Uu@W}d$z2^OYY3qD%L^F^qZ|H<>%1id@)%zE=@)0wdQaXT$y{$#F4{%{9m}oYrtL){s!ysj86an diff --git a/Tests/images/multiline_text_center.png b/Tests/images/multiline_text_center.png index f44d0783a0944986efdc62d4f0bcc7530b74ab5b..837c6382a97ecc064fddf85f902e2fba8ba0ce90 100644 GIT binary patch literal 3203 zcmbtWX*8Sb7Ir$AT6K=0T0^zeP(y=~nyUAhipE%{HET^FB3e=NP)Zd&6jc?6oK$0q zDosO!(4&Ycay5+@VwR$63<)B7zn-)1TKE5bf9&=C_}2d3{p@Ey&(3smxF#klD=Hu$ zAZBZ0=^`NTlNN9f5IzJ%yg#Z)K;XEYt>v$-F@LN~Btzs_ibCtDHsIh;6&zw&RTXaY zHpL+$-SBdw5m=K=c6)gaYuy3FWp9e55|bn-%*;PEO9m$jFwq1w|)X`yBre=Hlj7#aPDG z)VwS&S5{Jz674F~yfr&FM@%%^U;nt){ymAmx2=?CqgoK6FN>q^bxJzcD|B>psAuKd zVVTkC85zJE(=sv&WGoDG?65D@zm7uD(xU0+n7cgAij-Bgt40$)g7@LVg$p7DKc_n1 zxpOBlFwn+Ec>Lv1@Cik;fr}NdUj1Q&{Ic4z_N7hJ%&ZNE)70N;&rW4BnH?SG2=upa z-wq3%*zwGz-V4xkcXV`gb(LxYf~%t=^%M3wk(X|3m_Z@*4}JX#Lsg7g;pol5LrPJ) z%F1&qO;c_6<^;LgL3kpNR#!JKYkuaZUEjnTsIMRD*v;d&xtS&t4^IliHq*wODLA=V@sv|KAqk4HNPwG8`($TcSbu z7tfzZeHkcjXwXf*ynvK1hH#eOw8ym#`88^o9YQtV5>>5zrRp>k#! zfWheK=m2H>fX};r{d#y<_9S^}ZOymAFMXlqX04m9j?Uds&oq<4eN>un(k`ncylrWB zSCk9R*9C)bdV2CU`$1|dD*OZ9S~9?j*I`3ELvpSnl|s4SqV~)V3t&%M-iG&gc6O4u zll?2~9_3u7#}$D~{p`a}D$C+(UcE{i-yHS~FTI-VgK@IKx?r46DJr513jFnoZ@%_m zfl;m+2E`BpfuMP-?)WQ>wYe%fEbC=s_|#y6@g5UN-R5v==r9C&dzo=VN?Jyy>F$g< z(JN_daVT2`H2d(hu<-ylLf`(DtE-MS7K?>s(_t)5!k1#Gho@&4czkE){U|(Xjl``W zsRmeARac9&g4gEYWAA!z>x`^KwM-y%PJt23#Zfg7XzeQ{_W77=XcoR6_ywpparh{r%

C-~D+k#=R*`)Mfol`;4 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%0AI~}qU7P2X8@rDUK>UF9CWiCjXlr9v8+L-( zMjM~ytDS|Kmp1mfW{Qh))KpcctLnD~5fYm2*Hy$Eik(!%+B-VtW@j^O3U5%HsmV%2 zD_bSUz`*4$qB_cfxPxV)FTm}`s_&v;($Oo_xkx;I0DYmF{&QS}5kFZ%l(3fs_?!FbpvO}DhP6iNz=ieh1)O*<2KhNq~G zJd??!)k9ZjFryzjy|jjxadqQCT4$g^tnVYr5XkCiWq_!t=+!*?0tZE9Wrkk#*H4Kr zhfWAH0d{K0nJ1#o{jmpEB3yt%Ptf(bHhXzwqu${PEgJ4Jbq9*s`)+&eNw)XF0pgHrx@uiLT%YY6uF2 zn)3)7|C>7KqXS$QNeu?FIas{=?+q7ZG|^*GcPG9)l8N5RF~%ERk~Ip~QdjRTj~pyT zpekGz-d$@Ig1EkIt|(&6vudz;ZMWCm;Th}}Yvb|paV!>l z^uc)rg)5YS#_iDn8$1Ssv9n7-Ze_uu4S}*0JH3~L3J3_WP)R50ZOLaZW=J?XI+~f8 z(E^GXo!7KvQs~*rTm-GxI@VV}eLIt}5b-2{r#5(!c-yB>vvYHYdvjz44riDxFE7t1 z1JQuy%A|MyeNP_*0*Q!<_V`u|pgk(l#48|4Y3ch^_n3i@`ThdwOE?8(<)NV=N3j7G zD=R&{BYQ0>`?tntbZJ%ad4z_#dR_SXS995Dy$csA0mf-Go0U;24QyZRl$@L#5fOp0 z4hsuIBFRlNT2#nn411ZyWQ>gLea}l#6XR>}Tn(lI<)o8MCj0uP?;5A3rutUw5nViQ ziFEfr#i|(O{YzzVxo6hVcBYOkUsT2E__j@ZR1YYtgJFWLgy2!Luu-@KO;FYYB*_ z4WQCOLde?C;;VVuq#iMNsYl&lMMbC2hK^XoN;hpWV(I};%Y_tKnSOe;<5F7nSxJzl{WOE~kovWwjz+c& z8Zs;?DJjptwzxQPa^_f+sW0#E=jAGnpKpHdc2xMxXYi5#2t-X!IIKy6f0*Z#e`arI z=gS5GVtP75&jX1x!IP#u)`n=XGpb^I$2_d>2`9A?iNpzZILvT1zSGA+ji_6e^cj#~ z-}@qb$KwDs(#nYaSJ8b06Qd`k&3m}l@bS+-Pge5;9`OpI4LXYLvQxMonZiMR!^6W< zQ&RxQ)X6ET@qTX?jRv>~V8+tY(ugVy7SYYQU=2zCQ-P`!wVsyp)kXG&XE_SD_G6wA zL;IOum{H@Kpjb2I?%4n{RDs>gwqU3<_$T%fb8Nn~v*tXRN#F zPV2)KZ$;3jR8>^`{QcePaDn0B;h~|S0I3lX1}nUWaD85Nb#>}tq`zKfYl4v7*hu%M zwU+^3%MVAzEn$4Oas=4NJe-{J0ova?oT*=xSQOXswLmMK>p&TUA(BRkiHWG*EG&Ly zc54V3rhhKu(Sb1&;o)J+(5v&Syg7mq35JE(?wY2hnC75F#l;I5^Pg^Got zbG|BiKhF1U!G?EE0km;*b6+bWjO`wT<%)#)cnmACycW5EwH1drDlAy8qoex1YuOC7zET zKd!B+Geg5bnI@|l%$kYTBpy$hYwlp&!0b6w0^OBiJ3h|KIBza zR-RkxXQ9e?kro^FpLLxw7T2n(pry|E1*R&!{6@qGq*2HBWWct8AX3r@Fp1d{M|5$^ zqm|+7w__7(H}^Nqbaiw@BqgaRy39LQaH_@N8@G_D<_B((-?tmtE0nUbZ{ISbwgy}b zv!CqGIx9cr?8A?1?Pu?18Q$*-T-bPz)X>nlS^9#c z%@`c4x;G8{gqN3>0lDXJI5tk7nwy)gAq~uli34QoflCjpL+(w7G9XoEBNPtjW;oou z+4aG-)VUB2N(Ee>j5D5Y8q=bj9)t(RxL_ybI7$IH?uTQPxwcc2{{R(v`~WbLni z3T&|;N1Ngm5EwxJ`UnFpYC1f?+uQfWasT%8syxZ^*#Fx7|2r1`alkXNb$WX$PS*3+ OT9)u@SISJi;{FZ&TsSHK delta 2771 zcmY*Zc{tQ<7p@ehl#r!t*+yBiO)6PllSJ0ChAh!E#yV6O%TG~nmN&a>Gd^VSPMHwd z*AO!dCW&Dr46@UZ8Kdu4egAytk8?fOb)M%r_c`ajPxMKgNU|Joc-GX&&^9!0c_Q4z zW>uPJt*=kjc~*7sZ6Tc0Yj!K$>#B#SNulz0D=%&NvuBjd7L#_n4|55b)|;HlxY`#e zoRVRkIs0~in-u0Oq@~9Du;Srh>)dwtqs_~>*UO{23oKR?r#iU5YHlYlcdThPo6q8_Qr#&3JQfXwpS-(lNk&I z>-rhCKtgBu_R26422Jbn(j5Nyaf$ZMN=2mVsIS3d4Ny}f2w$U%>k7!ceED*QoUK(* zP@u1`4}m})Jb19Pvoo$878aI~kwI`E;&j7;9334|D3r6aGaP<^_LowIHVk&~&>?ib zLRt^KDO@qFXFj1|;hJnpdS<4*ot**{s&wM;6L?BimZP0r@y)W@pASD{1F~Yj#PP~p zFHUWM0=l}5EiL)CU8)d$izCFQrlvZ-!lELBh#y~OnLpoY^Bj}-(BIFfF*P;46t!DR zU|w8Sl#?rJY;;k|2%?!350zNu2jzMQwi|RTBvik7qpqPbSYv@kuW!tfMmr%wP?)y1 zB~CZ{)`^79;o)H$yg9mBs)QrP_jG<9NmJ|sy1IfUEARYy&+JK4oZ;VE8tsU*H#RoL zV01P^HyM3%{n%ild^d-WkMDD2g7OQ}YkOr*)c(-JC2F61M#^8`Zpg$F&f4H%Fqpd5 z%fdogdHMHEsS?}Nu`$&4bumdv&H`1jq2WvDY-mhF(NA3Ng#g6eyQ8iVwIOoANe+jD zs@A!5>5{%a9SPg|{=N1>;dE4de0+bt0i^+0TwccJ<~rNjzAx9v?R)g-(YUtRi*pZ% zQqe65jQEs{47=O6o4l#`|NQ54wz-IaKuTsNei$Ws&gDb+9c$}kdx9NdSU^BPuB_M4 z;AYv|SFaN5F6*Gb8a;tmL~$_x0LC`<_FYZRMc_pxI}?*<@B+u?h@E1y7bqVew8Ft8 z>gcE`@6N_-0yP7iftqXMkDbku9y6?Rs$~9^d7w zookLC8*?hY+0&qDh1IDB$wee4?Z~cwX^YX!PCPzDrFw=R<@o_v)kSgYPY3MAe&cbE z$kvafS^0uHrFmtq-Nd#6Zga;IKoA2D8%B-}^BxZeLBtX#0LvhrztW zg@MhjWoJgK|Jd7}V$3dwbL8-09UYxl_5{lkT61KBD{)RcFyh?U*ch)2IO^er`(U4n z291o3@x{eVCNpyP2f8O!;jy%|*jcN7mGzB{91TxnS63X^23quSK~d3>p`oB3YaVWH zleM+AiHUp<3Dj}Xf^Vbm0wzJW`2n{|JhO7FO+ z;WrPu#WN#WH8mn0kG~K=S6|G{%^f8OMe2cK0~Zxm+b?J04zm9cQFld_?btfa)xMTT zPQ_jh*(7205Efr|;jtpJ4wwNFDO?BY)&d!f7TFb_xJ~3M<>65EV6u+6`rW zU!dYG!a1yJaV9xSWBO}n!uj*(Ei5dAg@wWLY|flmvIh&%f;`dDKP^V-QStWno|F;BbWAzVw0Du2-0&~sZun&9r9XO%F!pFC- z1fN4f3#_|&V$-o$Y);N8X=#A@&5n*IlgS$!K{Rse93?+r=Ry2!Pt9y!Ei)HvtO2k$ z6D2DcXQb>>M6Hb1-EMeT=R|oI z08Ab@aG=)b02ddV#rphf7Jo{R=kHOe1Aaz%cz7U@r7q`^;^TWsq;Tf94DmGUnd>X0 z4~ucnpO+JfYG==Sh)C;4ln$f7elMf+Vv~D&dsUrl)cs`TGh7DD;RVn6 zdC5YWW*~}km%5?h;ky-%z+0!~f-8SFHZ?(Hz+%S{%gf7+R+`2|gEbde<1Yk0$)%W( z5t}uBw5-mVnHf6W^};uA6e>P3vGKv8eMrc5Yio3y`^88WY*h+B9lXA?c@J(99)6jI z3;Y`RVGWs=A}xJfOw(*%m*6k=`@{{Ne%qd24bU2Dh;FWL5TAeTT1mP@ zA&zb;OZaiew4u2il17MbEymW*eT=7E_7c=Y{{-zU`FWsIlTz?NoLkkL!^M9O=EoL6 z(gx1`2_JHmO_`^bSdlB-Tbidi4xuV>Myc7^qn|z@v~!slPKw;MP{54>1hOvmd6&mo z=OKozYo@N7ntE)lfceN)AD&F8?bkv`d^Dd-vOcLBRHv(~OhUq(R5DpC)-vr~1IBBQ zjVzB0W zW1nwNJXvy{x;wK+#|D6?g6uXbkyishJ=+A7ug zw0Cr{+3bn=0d#qs_|o&MX-V+xdmYCr(9_2M7;6PH%p30VHoM7&Xd#d&{AxE^Z+vPm zy)6xgE4L?vDX&g6{B3$MF+3k4sY_~u{>FA$#6tfta2Iz}%P1&l1I!j?P(Lf^)pD>W ztDr2qQrb{6^pv=`sH)R@=ep4KJLc^k#=(L*{pZm!6BWpf8)r6svt&Rf+t}E6iW{_@ z+KGZ>Xk58fMU9H>{c=)5VuoXWLtap$<>xNdrmN^iZmean#khNj%AbZHcq<$w#Ke98 zdz^6Xx-7F~j-Zm~(@I1Mhc}~*Ix(T=^GSu?d#eiJA$ZKQ+R1MfgNB@kU>P~JZ7Ytj zoipiS+T${hV`3H;7e`**>JYd5zYlDztpjI!h3UQR?Qjsclpe;`*7k&m2xEF$D}dfO z(Gb!Su@lsvcgYvvDuBwMGkv~tH+T-t6j?Jy*PikoIYLEMH-1MNZke?vp3KR?Zpqnl zTmAJ{v@5YCeB0mG_Z7V0SzO$WGTRqwZe8*cU6YgfrWY!lUK(X49gfBeAK}3S=b;IkvXfyFNcyL=IE|ms^&)$KzG zKs}~=WMsSj$q`9ONiHrfOw(TLBd$9YpKFxUWcaS7sq=A*@^2YXl5hNTtx9_Nmyk@a LS{jwZ-5>uK@T!eO diff --git a/Tests/images/multiline_text_spacing.png b/Tests/images/multiline_text_spacing.png index 3c3bc0f267d365d5a29531d9d0f18cc8e2aac7b6..3b367c7ddee8587239069ae3340b608364164438 100644 GIT binary patch delta 3127 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 diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index acc1cdb13..3ed3a2f02 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -155,7 +155,6 @@ class TestImageFont: draw.text((10, 10), txt, font=ttf) draw.rectangle((10, 10, 10 + size[0], 10 + size[1])) - # Epsilon ~.5 fails with FreeType 2.7 assert_image_similar_tofile( im, "Tests/images/rectangle_surrounding_text.png", 2.5 ) @@ -216,8 +215,7 @@ class TestImageFont: draw = ImageDraw.Draw(im) draw.text((0, 0), TEST_TEXT, font=ttf) - # Epsilon ~.5 fails with FreeType 2.7 - assert_image_similar_tofile(im, "Tests/images/multiline_text.png", 6.2) + assert_image_similar_tofile(im, "Tests/images/multiline_text.png", 0.01) # Test that text() can pass on additional arguments # to multiline_text() @@ -232,9 +230,8 @@ class TestImageFont: draw = ImageDraw.Draw(im) draw.multiline_text((0, 0), TEST_TEXT, font=ttf, align=align) - # Epsilon ~.5 fails with FreeType 2.7 assert_image_similar_tofile( - im, "Tests/images/multiline_text" + ext + ".png", 6.2 + im, "Tests/images/multiline_text" + ext + ".png", 0.01 ) def test_unknown_align(self): @@ -289,8 +286,7 @@ class TestImageFont: draw = ImageDraw.Draw(im) draw.multiline_text((0, 0), TEST_TEXT, font=ttf, spacing=10) - # Epsilon ~.5 fails with FreeType 2.7 - assert_image_similar_tofile(im, "Tests/images/multiline_text_spacing.png", 6.2) + assert_image_similar_tofile(im, "Tests/images/multiline_text_spacing.png", 2.5) def test_rotated_transposed_font(self): img_grey = Image.new("L", (100, 100))