diff --git a/CHANGES.rst b/CHANGES.rst index c3e60acff..55eabefd4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,9 @@ Changelog (Pillow) 9.3.0 (unreleased) ------------------ +- Raise an error when allocating translucent color to RGB palette #6654 + [jsbueno, radarhere] + - Added reading of TIFF child images #6569 [radarhere] diff --git a/Tests/test_image_access.py b/Tests/test_image_access.py index bb09a7708..a000cb64c 100644 --- a/Tests/test_image_access.py +++ b/Tests/test_image_access.py @@ -345,13 +345,14 @@ class TestCffi(AccessTest): @pytest.mark.parametrize("mode", ("P", "PA")) def test_p_putpixel_rgb_rgba(self, mode): - for color in [(255, 0, 0), (255, 0, 0, 127)]: + for color in ((255, 0, 0), (255, 0, 0, 127 if mode == "PA" else 255)): im = Image.new(mode, (1, 1)) access = PyAccess.new(im, False) access.putpixel((0, 0), color) - alpha = color[3] if len(color) == 4 and mode == "PA" else 255 - assert im.convert("RGBA").getpixel((0, 0)) == (255, 0, 0, alpha) + if len(color) == 3: + color += (255,) + assert im.convert("RGBA").getpixel((0, 0)) == color class TestImagePutPixelError(AccessTest): diff --git a/Tests/test_imagepalette.py b/Tests/test_imagepalette.py index 475d249ed..5bda28117 100644 --- a/Tests/test_imagepalette.py +++ b/Tests/test_imagepalette.py @@ -50,6 +50,16 @@ def test_getcolor(): palette.getcolor("unknown") +def test_getcolor_rgba_color_rgb_palette(): + palette = ImagePalette.ImagePalette("RGB") + + # Opaque RGBA colors are converted + assert palette.getcolor((0, 0, 0, 255)) == palette.getcolor((0, 0, 0)) + + with pytest.raises(ValueError): + palette.getcolor((0, 0, 0, 128)) + + @pytest.mark.parametrize( "index, palette", [ diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index 8be7f0f10..b3a7cdb98 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -955,6 +955,11 @@ def truetype(font=None, size=10, index=0, encoding="", layout_engine=None): encoding of any text provided in subsequent operations. :param layout_engine: Which layout engine to use, if available: :data:`.ImageFont.Layout.BASIC` or :data:`.ImageFont.Layout.RAQM`. + If it is available, Raqm layout will be used by default. + Otherwise, basic layout will be used. + + Raqm layout is recommended for all non-English text. If Raqm layout + is not required, basic layout will have better performance. You can check support for Raqm layout using :py:func:`PIL.features.check_feature` with ``feature="raqm"``. diff --git a/src/PIL/ImagePalette.py b/src/PIL/ImagePalette.py index b73b2cd9d..fe76c86f4 100644 --- a/src/PIL/ImagePalette.py +++ b/src/PIL/ImagePalette.py @@ -115,7 +115,11 @@ class ImagePalette: raise ValueError("palette contains raw palette data") if isinstance(color, tuple): if self.mode == "RGB": - if len(color) == 4 and color[3] == 255: + if len(color) == 4: + if color[3] != 255: + raise ValueError( + "cannot add non-opaque RGBA color to RGB palette" + ) color = color[:3] elif self.mode == "RGBA": if len(color) == 3: diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index f4515468f..ad7b1ddb6 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -281,9 +281,9 @@ deps = { "libs": [r"imagequant.lib"], }, "harfbuzz": { - "url": "https://github.com/harfbuzz/harfbuzz/archive/5.2.0.zip", - "filename": "harfbuzz-5.2.0.zip", - "dir": "harfbuzz-5.2.0", + "url": "https://github.com/harfbuzz/harfbuzz/archive/5.3.0.zip", + "filename": "harfbuzz-5.3.0.zip", + "dir": "harfbuzz-5.3.0", "build": [ cmd_cmake("-DHB_HAVE_FREETYPE:BOOL=TRUE"), cmd_nmake(target="clean"),