From 41a7bfe1c188bda64c5fcc84d6518084d742de9f Mon Sep 17 00:00:00 2001 From: nulano Date: Mon, 5 Sep 2022 06:49:48 +0200 Subject: [PATCH 01/12] append dependency licenses to windows wheels on GHA --- .github/workflows/test-windows.yml | 16 +++++++++++++ winbuild/build_prepare.py | 37 +++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index b9accfdf9a5..ba72a7018b3 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -181,6 +181,22 @@ jobs: id: wheel if: "github.event_name != 'pull_request'" run: | + setlocal EnableDelayedExpansion + for %%f in (winbuild\build\license\*) do ( + set x=%%~nf + rem Skip FriBiDi license, it is not included in the wheel. + set fribidi=!x:~0,7! + if NOT !fribidi!==fribidi ( + rem Skip imagequant license, it is not included in the wheel. + set libimagequant=!x:~0,13! + if NOT !libimagequant!==libimagequant ( + echo. >> LICENSE + echo ===== %%~nf ===== >> LICENSE + echo. >> LICENSE + type %%f >> LICENSE + ) + ) + ) for /f "tokens=3 delims=/" %%a in ("${{ github.ref }}") do echo ::set-output name=dist::dist-%%a winbuild\\build\\build_pillow.cmd --disable-imagequant bdist_wheel shell: cmd diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index 94e5dd87114..e878f4c8e28 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -1,5 +1,6 @@ import os import platform +import re import shutil import struct import subprocess @@ -111,6 +112,11 @@ def cmd_msbuild( + "/libjpeg-turbo/files/2.1.4/libjpeg-turbo-2.1.4.tar.gz/download", "filename": "libjpeg-turbo-2.1.4.tar.gz", "dir": "libjpeg-turbo-2.1.4", + "license": ["README.ijg", "LICENSE.md"], + "license_pattern": ( + "(LEGAL ISSUES\n============\n\n.+?)\n\nREFERENCES\n==========" + ".+(libjpeg-turbo Licenses\n======================\n\n.+)$" + ), "build": [ cmd_cmake( [ @@ -135,6 +141,8 @@ def cmd_msbuild( "url": "https://zlib.net/zlib1212.zip", "filename": "zlib1212.zip", "dir": "zlib-1.2.12", + "license": "README", + "license_pattern": "Copyright notice:\n\n(.+)$", "build": [ cmd_nmake(r"win32\Makefile.msc", "clean"), cmd_nmake(r"win32\Makefile.msc", "zlib.lib"), @@ -147,6 +155,7 @@ def cmd_msbuild( "url": "https://download.osgeo.org/libtiff/tiff-4.4.0.tar.gz", "filename": "tiff-4.4.0.tar.gz", "dir": "tiff-4.4.0", + "license": "COPYRIGHT", "build": [ cmd_cmake("-DBUILD_SHARED_LIBS:BOOL=OFF"), cmd_nmake(target="clean"), @@ -160,6 +169,7 @@ def cmd_msbuild( "url": "http://downloads.webmproject.org/releases/webp/libwebp-1.2.4.tar.gz", "filename": "libwebp-1.2.4.tar.gz", "dir": "libwebp-1.2.4", + "license": "COPYING", "build": [ cmd_rmdir(r"output\release-static"), # clean cmd_nmake( @@ -176,6 +186,7 @@ def cmd_msbuild( "url": SF_PROJECTS + "/libpng/files/libpng16/1.6.37/lpng1637.zip/download", "filename": "lpng1637.zip", "dir": "lpng1637", + "license": "LICENSE", "build": [ # lint: do not inline cmd_cmake(("-DPNG_SHARED:BOOL=OFF", "-DPNG_TESTS:BOOL=OFF")), @@ -190,6 +201,7 @@ def cmd_msbuild( "url": "https://download.savannah.gnu.org/releases/freetype/freetype-2.12.1.tar.gz", # noqa: E501 "filename": "freetype-2.12.1.tar.gz", "dir": "freetype-2.12.1", + "license": ["LICENSE.TXT", r"docs\FTL.TXT", r"docs\GPLv2.TXT"], "patch": { r"builds\windows\vc2010\freetype.vcxproj": { # freetype setting is /MD for .dll and /MT for .lib, we need /MD @@ -225,6 +237,7 @@ def cmd_msbuild( "url": SF_PROJECTS + "/lcms/files/lcms/2.13/lcms2-2.13.1.tar.gz/download", "filename": "lcms2-2.13.1.tar.gz", "dir": "lcms2-2.13.1", + "license": "COPYING", "patch": { r"Projects\VC2022\lcms2_static\lcms2_static.vcxproj": { # default is /MD for x86 and /MT for x64, we need /MD always @@ -250,6 +263,7 @@ def cmd_msbuild( "url": "https://github.com/uclouvain/openjpeg/archive/v2.5.0.tar.gz", "filename": "openjpeg-2.5.0.tar.gz", "dir": "openjpeg-2.5.0", + "license": "LICENSE", "build": [ cmd_cmake(("-DBUILD_THIRDPARTY:BOOL=OFF", "-DBUILD_SHARED_LIBS:BOOL=OFF")), cmd_nmake(target="clean"), @@ -264,6 +278,7 @@ def cmd_msbuild( "url": "https://github.com/ImageOptim/libimagequant/archive/e4c1334be0eff290af5e2b4155057c2953a313ab.zip", # noqa: E501 "filename": "libimagequant-e4c1334be0eff290af5e2b4155057c2953a313ab.zip", "dir": "libimagequant-e4c1334be0eff290af5e2b4155057c2953a313ab", + "license": "COPYRIGHT", "patch": { "CMakeLists.txt": { "if(OPENMP_FOUND)": "if(false)", @@ -284,6 +299,7 @@ def cmd_msbuild( "url": "https://github.com/harfbuzz/harfbuzz/archive/5.1.0.zip", "filename": "harfbuzz-5.1.0.zip", "dir": "harfbuzz-5.1.0", + "license": "COPYING", "build": [ cmd_cmake("-DHB_HAVE_FREETYPE:BOOL=TRUE"), cmd_nmake(target="clean"), @@ -296,6 +312,7 @@ def cmd_msbuild( "url": "https://github.com/fribidi/fribidi/archive/v1.0.12.zip", "filename": "fribidi-1.0.12.zip", "dir": "fribidi-1.0.12", + "license": "COPYING", "build": [ cmd_copy(r"{winbuild_dir}\fribidi.cmake", r"CMakeLists.txt"), cmd_cmake(), @@ -431,6 +448,21 @@ def build_dep(name): extract_dep(dep["url"], dep["filename"]) + licenses = dep["license"] + if isinstance(licenses, str): + licenses = [licenses] + license_text = "" + for license_file in licenses: + with open(os.path.join(sources_dir, dir, license_file)) as f: + license_text += f.read() + if "license_pattern" in dep: + match = re.search(dep["license_pattern"], license_text, re.DOTALL) + license_text = "\n".join(match.groups()) + assert len(license_text) > 50 + with open(os.path.join(license_dir, f"{dir}.txt"), "w") as f: + print(f"Writing license {dir}.txt") + f.write(license_text) + for patch_file, patch_list in dep.get("patch", {}).items(): patch_file = os.path.join(sources_dir, dir, patch_file.format(**prefs)) with open(patch_file) as f: @@ -551,10 +583,12 @@ def build_pillow(): bin_dir = os.path.join(build_dir, "bin") # directory for storing project files sources_dir = build_dir + sources_dir + # copy dependency licenses to this directory + license_dir = os.path.join(build_dir, "license") shutil.rmtree(build_dir, ignore_errors=True) os.makedirs(build_dir, exist_ok=False) - for path in [inc_dir, lib_dir, bin_dir, sources_dir]: + for path in [inc_dir, lib_dir, bin_dir, sources_dir, license_dir]: os.makedirs(path, exist_ok=True) prefs = { @@ -572,6 +606,7 @@ def build_pillow(): "lib_dir": lib_dir, "bin_dir": bin_dir, "src_dir": sources_dir, + "license_dir": license_dir, # Compilers / Tools **msvs, "cmake": "cmake.exe", # TODO find CMAKE automatically From 9699a0e1d6ee4859f1b9da0e9e7a45082f9f4c69 Mon Sep 17 00:00:00 2001 From: nulano Date: Mon, 5 Sep 2022 10:13:52 +0200 Subject: [PATCH 02/12] test libtiff with lzma --- Tests/images/hopper_lzma.tif | Bin 0 -> 30789 bytes Tests/test_file_libtiff.py | 14 ++++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 Tests/images/hopper_lzma.tif diff --git a/Tests/images/hopper_lzma.tif b/Tests/images/hopper_lzma.tif new file mode 100644 index 0000000000000000000000000000000000000000..d7ca089fc40949c731fdc7f354ff1072f026039a GIT binary patch literal 30789 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

yOGTie&81$CleX~bmQxxgb>64rCPjpf6|)jF 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 Date: Mon, 5 Sep 2022 11:05:18 +0200 Subject: [PATCH 03/12] compile libtiff with liblzma on windows --- .github/workflows/test-windows.yml | 4 +++ winbuild/build_prepare.py | 41 +++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index ba72a7018b3..23d9078064c 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -86,6 +86,10 @@ jobs: if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_zlib.cmd" + - name: Build dependencies / xz + if: steps.build-cache.outputs.cache-hit != 'true' + run: "& winbuild\\build\\build_dep_xz.cmd" + - name: Build dependencies / LibTiff if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_libtiff.cmd" diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index e878f4c8e28..0ac9d3c816b 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -151,11 +151,46 @@ def cmd_msbuild( "headers": [r"z*.h"], "libs": [r"*.lib"], }, + "xz": { + "url": SF_PROJECTS + "/lzmautils/files/xz-5.2.6.tar.gz/download", + "filename": "xz-5.2.6.tar.gz", + "dir": "xz-5.2.6", + "license": "COPYING", + "patch": { + r"src\liblzma\api\lzma.h": { + "#ifndef LZMA_API_IMPORT": "#ifndef LZMA_API_IMPORT\n#define LZMA_API_STATIC", # noqa: E501 + }, + r"windows\vs2019\liblzma.vcxproj": { + # retarget to default toolset (selected by vcvarsall.bat) + "v142": "$(DefaultPlatformToolset)", # noqa: E501 + # retarget to latest (selected by vcvarsall.bat) + "10.0": "$(WindowsSDKVersion)", # noqa: E501 + }, + }, + "build": [ + cmd_msbuild(r"windows\vs2019\liblzma.vcxproj", "Release", "Clean"), + cmd_msbuild(r"windows\vs2019\liblzma.vcxproj", "Release", "Build"), + cmd_mkdir(r"{inc_dir}\lzma"), + cmd_copy(r"src\liblzma\api\lzma\*.h", r"{inc_dir}\lzma"), + ], + "headers": [r"src\liblzma\api\lzma.h"], + "libs": [r"windows\vs2019\Release\{msbuild_arch}\liblzma\liblzma.lib"], + }, "libtiff": { "url": "https://download.osgeo.org/libtiff/tiff-4.4.0.tar.gz", "filename": "tiff-4.4.0.tar.gz", "dir": "tiff-4.4.0", "license": "COPYRIGHT", + "patch": { + r"cmake\LZMACodec.cmake": { + # fix typo + "${{LZMA_FOUND}}": "${{LIBLZMA_FOUND}}", + }, + r"libtiff\tif_lzma.c": { + # link against liblzma.lib + "#ifdef LZMA_SUPPORT": '#ifdef LZMA_SUPPORT\n#pragma comment(lib, "liblzma.lib")', # noqa: E501 + }, + }, "build": [ cmd_cmake("-DBUILD_SHARED_LIBS:BOOL=OFF"), cmd_nmake(target="clean"), @@ -216,7 +251,7 @@ def cmd_msbuild( "": "zlib.lib;libpng16.lib", # noqa: E501 }, r"src/autofit/afshaper.c": { - # link against harfbuzz.lib once it becomes available + # link against harfbuzz.lib "#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ": '#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ\n#pragma comment(lib, "harfbuzz.lib")', # noqa: E501 }, }, @@ -423,8 +458,8 @@ def write_script(name, lines): name = os.path.join(build_dir, name) lines = [line.format(**prefs) for line in lines] print("Writing " + name) - with open(name, "w") as f: - f.write("\n\r".join(lines)) + with open(name, "w", newline="") as f: + f.write(os.linesep.join(lines)) if verbose: for line in lines: print(" " + line) From a7df33551ccffc6aea7ba4c65ccc4f769e1eaede Mon Sep 17 00:00:00 2001 From: nulano Date: Mon, 5 Sep 2022 11:58:12 +0200 Subject: [PATCH 04/12] libopenjpeg has no dependencies, skip searching for dependencies of openjpeg binaries on windows --- winbuild/build_prepare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index 0ac9d3c816b..9772883d3e3 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -300,7 +300,7 @@ def cmd_msbuild( "dir": "openjpeg-2.5.0", "license": "LICENSE", "build": [ - cmd_cmake(("-DBUILD_THIRDPARTY:BOOL=OFF", "-DBUILD_SHARED_LIBS:BOOL=OFF")), + cmd_cmake(("-DBUILD_CODEC:BOOL=OFF", "-DBUILD_SHARED_LIBS:BOOL=OFF")), cmd_nmake(target="clean"), cmd_nmake(target="openjp2"), cmd_mkdir(r"{inc_dir}\openjpeg-2.5.0"), From ffedfe034a50318e579a5d389537b65f91f3b209 Mon Sep 17 00:00:00 2001 From: nulano Date: Mon, 5 Sep 2022 11:58:42 +0200 Subject: [PATCH 05/12] test libtiff with webp compression --- Tests/images/hopper_webp.png | Bin 0 -> 27598 bytes Tests/images/hopper_webp.tif | Bin 0 -> 3651 bytes Tests/test_file_libtiff.py | 13 +++++++++++++ 3 files changed, 13 insertions(+) create mode 100644 Tests/images/hopper_webp.png create mode 100644 Tests/images/hopper_webp.tif diff --git a/Tests/images/hopper_webp.png b/Tests/images/hopper_webp.png new file mode 100644 index 0000000000000000000000000000000000000000..94b927ac24a337fd22d74cededf764dfeed026ef GIT binary patch literal 27598 zcmV*bKvchpP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 Date: Mon, 5 Sep 2022 12:48:42 +0200 Subject: [PATCH 06/12] compile libtiff with webp on windows --- .github/workflows/test-windows.yml | 8 +++--- winbuild/build_prepare.py | 43 ++++++++++++++++++------------ 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 23d9078064c..e6452ceb45b 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -90,14 +90,14 @@ jobs: if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_xz.cmd" - - name: Build dependencies / LibTiff - if: steps.build-cache.outputs.cache-hit != 'true' - run: "& winbuild\\build\\build_dep_libtiff.cmd" - - name: Build dependencies / WebP if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_libwebp.cmd" + - name: Build dependencies / LibTiff + if: steps.build-cache.outputs.cache-hit != 'true' + run: "& winbuild\\build\\build_dep_libtiff.cmd" + # for FreeType CBDT/SBIX font support - name: Build dependencies / libpng if: steps.build-cache.outputs.cache-hit != 'true' diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index 9772883d3e3..dfcbbb979b8 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -176,6 +176,28 @@ def cmd_msbuild( "headers": [r"src\liblzma\api\lzma.h"], "libs": [r"windows\vs2019\Release\{msbuild_arch}\liblzma\liblzma.lib"], }, + "libwebp": { + "url": "http://downloads.webmproject.org/releases/webp/libwebp-1.2.4.tar.gz", + "filename": "libwebp-1.2.4.tar.gz", + "dir": "libwebp-1.2.4", + "license": "COPYING", + "build": [ + cmd_rmdir(r"output\release-static"), # clean + cmd_nmake( + "Makefile.vc", + "all", + [ + "CFG=release-static", + "OBJDIR=output", + "ARCH={architecture}", + "LIBWEBP_BASENAME=webp", + ], + ), + cmd_mkdir(r"{inc_dir}\webp"), + cmd_copy(r"src\webp\*.h", r"{inc_dir}\webp"), + ], + "libs": [r"output\release-static\{architecture}\lib\*.lib"], + }, "libtiff": { "url": "https://download.osgeo.org/libtiff/tiff-4.4.0.tar.gz", "filename": "tiff-4.4.0.tar.gz", @@ -190,6 +212,10 @@ def cmd_msbuild( # link against liblzma.lib "#ifdef LZMA_SUPPORT": '#ifdef LZMA_SUPPORT\n#pragma comment(lib, "liblzma.lib")', # noqa: E501 }, + r"libtiff\tif_webp.c": { + # link against webp.lib + "#ifdef WEBP_SUPPORT": '#ifdef WEBP_SUPPORT\n#pragma comment(lib, "webp.lib")', # noqa: E501 + }, }, "build": [ cmd_cmake("-DBUILD_SHARED_LIBS:BOOL=OFF"), @@ -200,23 +226,6 @@ def cmd_msbuild( "libs": [r"libtiff\*.lib"], # "bins": [r"libtiff\*.dll"], }, - "libwebp": { - "url": "http://downloads.webmproject.org/releases/webp/libwebp-1.2.4.tar.gz", - "filename": "libwebp-1.2.4.tar.gz", - "dir": "libwebp-1.2.4", - "license": "COPYING", - "build": [ - cmd_rmdir(r"output\release-static"), # clean - cmd_nmake( - "Makefile.vc", - "all", - ["CFG=release-static", "OBJDIR=output", "ARCH={architecture}"], - ), - cmd_mkdir(r"{inc_dir}\webp"), - cmd_copy(r"src\webp\*.h", r"{inc_dir}\webp"), - ], - "libs": [r"output\release-static\{architecture}\lib\*.lib"], - }, "libpng": { "url": SF_PROJECTS + "/libpng/files/libpng16/1.6.37/lpng1637.zip/download", "filename": "lpng1637.zip", From b22c66eeb80309bd14c5f3b2d802ab7a8b66e874 Mon Sep 17 00:00:00 2001 From: nulano Date: Mon, 5 Sep 2022 13:44:12 +0200 Subject: [PATCH 07/12] skip libtiif webp test when libtiff is too old --- Tests/test_file_libtiff.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Tests/test_file_libtiff.py b/Tests/test_file_libtiff.py index e32ce87af70..f1d290a32e7 100644 --- a/Tests/test_file_libtiff.py +++ b/Tests/test_file_libtiff.py @@ -3,6 +3,7 @@ import itertools import os import re +import sys from collections import namedtuple import pytest @@ -844,6 +845,8 @@ def test_lzma(self, capfd): captured = capfd.readouterr() if "LZMA compression support is not configured" in captured.err: pytest.skip("LZMA compression support is not configured") + sys.stdout.write(captured.out) + sys.stderr.write(captured.err) raise def test_webp(self, capfd): @@ -857,6 +860,15 @@ def test_webp(self, capfd): captured = capfd.readouterr() if "WEBP compression support is not configured" in captured.err: pytest.skip("WEBP compression support is not configured") + if ( + "Compression scheme 50001 strip decoding is not implemented" + in captured.err + ): + pytest.skip( + "Compression scheme 50001 strip decoding is not implemented" + ) + sys.stdout.write(captured.out) + sys.stderr.write(captured.err) raise def test_lzw(self): From 8b1f92a7567a9c8a55b0c6809e072c277b869f5f Mon Sep 17 00:00:00 2001 From: nulano Date: Mon, 5 Sep 2022 14:58:41 +0200 Subject: [PATCH 08/12] restore py_vcruntime_redist --- winbuild/build_prepare.py | 1 + 1 file changed, 1 insertion(+) diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index dfcbbb979b8..2dafb3d1871 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -553,6 +553,7 @@ def build_pillow(): cmd_cd("{pillow_dir}"), *prefs["header"], cmd_set("DISTUTILS_USE_SDK", "1"), # use same compiler to build Pillow + cmd_set("py_vcruntime_redist", "true"), # always use /MD, never /MT r'"{python_dir}\{python_exe}" setup.py build_ext --vendor-raqm --vendor-fribidi %*', # noqa: E501 ] From 17e5f1eb3b6b68a1775064194a85f3a562c5faca Mon Sep 17 00:00:00 2001 From: nulano Date: Wed, 7 Sep 2022 19:31:31 +0200 Subject: [PATCH 09/12] add recommended build flag for webp set to the default value --- winbuild/build_prepare.py | 1 + 1 file changed, 1 insertion(+) diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index 2dafb3d1871..104d52ac530 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -188,6 +188,7 @@ def cmd_msbuild( "all", [ "CFG=release-static", + "RTLIBCFG=dynamic", "OBJDIR=output", "ARCH={architecture}", "LIBWEBP_BASENAME=webp", From 2f95e49b3659203c4e8d166280f5807f51a64306 Mon Sep 17 00:00:00 2001 From: nulano Date: Wed, 7 Sep 2022 19:34:34 +0200 Subject: [PATCH 10/12] add test using woff2 font with freetype --- Tests/fonts/LICENSE.txt | 1 + Tests/fonts/OpenSans.woff2 | Bin 0 -> 16740 bytes Tests/images/test_woff2.png | Bin 0 -> 6724 bytes Tests/test_imagefont.py | 18 ++++++++++++++++++ 4 files changed, 19 insertions(+) create mode 100644 Tests/fonts/OpenSans.woff2 create mode 100644 Tests/images/test_woff2.png diff --git a/Tests/fonts/LICENSE.txt b/Tests/fonts/LICENSE.txt index 104ff677cad..da559b3d3f2 100644 --- a/Tests/fonts/LICENSE.txt +++ b/Tests/fonts/LICENSE.txt @@ -8,6 +8,7 @@ TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny ArefRuqaa-Regular.ttf, from https://github.com/google/fonts/tree/master/ofl/arefruqaa ter-x20b.pcf, from http://terminus-font.sourceforge.net/ BungeeColor-Regular_colr_Windows.ttf, from https://github.com/djrrb/bungee +OpenSans.woff2, from https://fonts.googleapis.com/css?family=Open+Sans All of the above fonts are published under the SIL Open Font License (OFL) v1.1 (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), which allows you to copy, modify, and redistribute them if you need to. diff --git a/Tests/fonts/OpenSans.woff2 b/Tests/fonts/OpenSans.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..15339ea9ccdd3bc54b25dfe54800f1c3bb730d26 GIT binary patch literal 16740 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 Qc*TNHRn$@_xohhGKUSIoPyhe` literal 0 HcmV?d00001 diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index 16da87d469a..b9a0f6db54b 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -1064,6 +1064,24 @@ def test_colr_mask(self): assert_image_similar_tofile(im, "Tests/images/colr_bungee_mask.png", 22) + def test_woff2(self): + try: + font = ImageFont.truetype( + "Tests/fonts/OpenSans.woff2", + size=64, + layout_engine=self.LAYOUT_ENGINE, + ) + except OSError as e: + assert str(e) in ("unimplemented feature", "unknown file format") + pytest.skip("FreeType compiled without brotli or WOFF2 support") + + im = Image.new("RGB", (350, 100), "white") + d = ImageDraw.Draw(im) + + d.text((15, 5), "OpenSans", "black", font=font) + + assert_image_similar_tofile(im, "Tests/images/test_woff2.png", 5) + def test_fill_deprecation(self): font = self.get_font() with pytest.warns(DeprecationWarning): From e9af622a2bb67548172dea903f9708e4ffd7f0fb Mon Sep 17 00:00:00 2001 From: nulano Date: Wed, 7 Sep 2022 19:59:55 +0200 Subject: [PATCH 11/12] build brotli on Windows --- .github/workflows/test-windows.yml | 5 +++++ winbuild/build_prepare.py | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index e6452ceb45b..a231bb78c31 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -103,6 +103,11 @@ jobs: if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_libpng.cmd" + # for FreeType WOFF2 font support + - name: Build dependencies / brotli + if: steps.build-cache.outputs.cache-hit != 'true' + run: "& winbuild\\build\\build_dep_brotli.cmd" + - name: Build dependencies / FreeType if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_freetype.cmd" diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index 104d52ac530..e289027fe51 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -242,6 +242,20 @@ def cmd_msbuild( "headers": [r"png*.h"], "libs": [r"libpng16.lib"], }, + "brotli": { + "url": "https://github.com/google/brotli/archive/refs/tags/v1.0.9.tar.gz", + "filename": "brotli-1.0.9.tar.gz", + "dir": "brotli-1.0.9", + "license": "LICENSE", + "build": [ + cmd_cmake(), + cmd_nmake(target="clean"), + cmd_nmake(target="brotlicommon-static"), + cmd_nmake(target="brotlidec-static"), + cmd_xcopy(r"c\include", "{inc_dir}"), + ], + "libs": ["*.lib"], + }, "freetype": { "url": "https://download.savannah.gnu.org/releases/freetype/freetype-2.12.1.tar.gz", # noqa: E501 "filename": "freetype-2.12.1.tar.gz", @@ -255,10 +269,10 @@ def cmd_msbuild( '': '\n $(WindowsSDKVersion)', # noqa: E501 }, r"builds\windows\vc2010\freetype.user.props": { - "": "FT_CONFIG_OPTION_SYSTEM_ZLIB;FT_CONFIG_OPTION_USE_PNG;FT_CONFIG_OPTION_USE_HARFBUZZ", # noqa: E501 + "": "FT_CONFIG_OPTION_SYSTEM_ZLIB;FT_CONFIG_OPTION_USE_PNG;FT_CONFIG_OPTION_USE_HARFBUZZ;FT_CONFIG_OPTION_USE_BROTLI", # noqa: E501 "": r"{dir_harfbuzz}\src;{inc_dir}", # noqa: E501 "": "{lib_dir}", # noqa: E501 - "": "zlib.lib;libpng16.lib", # noqa: E501 + "": "zlib.lib;libpng16.lib;brotlicommon-static.lib;brotlidec-static.lib", # noqa: E501 }, r"src/autofit/afshaper.c": { # link against harfbuzz.lib From ed990abed4fe1c73d13fb4c17a8ca07af00718cf Mon Sep 17 00:00:00 2001 From: nulano Date: Sun, 2 Oct 2022 07:05:18 +0100 Subject: [PATCH 12/12] windows: update xz to 5.2.7, update libpng to 1.6.38 --- winbuild/build_prepare.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index 414857fc25a..573020ca393 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -152,9 +152,9 @@ def cmd_msbuild( "libs": [r"*.lib"], }, "xz": { - "url": SF_PROJECTS + "/lzmautils/files/xz-5.2.6.tar.gz/download", - "filename": "xz-5.2.6.tar.gz", - "dir": "xz-5.2.6", + "url": SF_PROJECTS + "/lzmautils/files/xz-5.2.7.tar.gz/download", + "filename": "xz-5.2.7.tar.gz", + "dir": "xz-5.2.7", "license": "COPYING", "patch": { r"src\liblzma\api\lzma.h": { @@ -228,9 +228,9 @@ def cmd_msbuild( # "bins": [r"libtiff\*.dll"], }, "libpng": { - "url": SF_PROJECTS + "/libpng/files/libpng16/1.6.37/lpng1637.zip/download", - "filename": "lpng1637.zip", - "dir": "lpng1637", + "url": SF_PROJECTS + "/libpng/files/libpng16/1.6.38/lpng1638.zip/download", + "filename": "lpng1638.zip", + "dir": "lpng1638", "license": "LICENSE", "build": [ # lint: do not inline