mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-12 18:26:17 +03:00
Various fixes
This commit is contained in:
parent
d44e9fccb1
commit
d63caf266d
|
@ -41,7 +41,7 @@ import warnings
|
||||||
from collections.abc import Callable, MutableMapping
|
from collections.abc import Callable, MutableMapping
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import IO, TYPE_CHECKING, Any, Literal, Protocol, Sequence, cast, overload
|
from typing import IO, TYPE_CHECKING, Any, Literal, Protocol, Sequence, cast
|
||||||
|
|
||||||
# VERSION was removed in Pillow 6.0.0.
|
# VERSION was removed in Pillow 6.0.0.
|
||||||
# PILLOW_VERSION was removed in Pillow 9.0.0.
|
# PILLOW_VERSION was removed in Pillow 9.0.0.
|
||||||
|
@ -483,7 +483,9 @@ def _getscaleoffset(expr):
|
||||||
|
|
||||||
|
|
||||||
class _GetDataTransform(Protocol):
|
class _GetDataTransform(Protocol):
|
||||||
def getdata(self) -> tuple[Transform, Sequence[float]]: ...
|
def getdata(
|
||||||
|
self,
|
||||||
|
) -> tuple[Transform, Sequence[Any]]: ...
|
||||||
|
|
||||||
|
|
||||||
class Image:
|
class Image:
|
||||||
|
@ -2690,41 +2692,11 @@ class Image:
|
||||||
|
|
||||||
# FIXME: the different transform methods need further explanation
|
# FIXME: the different transform methods need further explanation
|
||||||
# instead of bloating the method docs, add a separate chapter.
|
# instead of bloating the method docs, add a separate chapter.
|
||||||
@overload
|
|
||||||
def transform(
|
|
||||||
self,
|
|
||||||
size: tuple[int, int],
|
|
||||||
method: Transform | ImageTransformHandler,
|
|
||||||
data: Sequence[float],
|
|
||||||
resample: int = Resampling.NEAREST,
|
|
||||||
fill: int = 1,
|
|
||||||
fillcolor: float | tuple[float, ...] | str | None = None,
|
|
||||||
) -> Image: ...
|
|
||||||
@overload
|
|
||||||
def transform(
|
|
||||||
self,
|
|
||||||
size: tuple[int, int],
|
|
||||||
method: _GetDataTransform,
|
|
||||||
data: None = None,
|
|
||||||
resample: int = Resampling.NEAREST,
|
|
||||||
fill: int = 1,
|
|
||||||
fillcolor: float | tuple[float, ...] | str | None = None,
|
|
||||||
) -> Image: ...
|
|
||||||
@overload
|
|
||||||
def transform(
|
def transform(
|
||||||
self,
|
self,
|
||||||
size: tuple[int, int],
|
size: tuple[int, int],
|
||||||
method: Transform | ImageTransformHandler | _GetDataTransform,
|
method: Transform | ImageTransformHandler | _GetDataTransform,
|
||||||
data: Sequence[float] | None = None,
|
data: Sequence[Any] | None = None,
|
||||||
resample: int = Resampling.NEAREST,
|
|
||||||
fill: int = 1,
|
|
||||||
fillcolor: float | tuple[float, ...] | str | None = None,
|
|
||||||
) -> Image: ...
|
|
||||||
def transform(
|
|
||||||
self,
|
|
||||||
size: tuple[int, int],
|
|
||||||
method: Transform | ImageTransformHandler | _GetDataTransform,
|
|
||||||
data: Sequence[float] | None = None,
|
|
||||||
resample: int = Resampling.NEAREST,
|
resample: int = Resampling.NEAREST,
|
||||||
fill: int = 1,
|
fill: int = 1,
|
||||||
fillcolor: float | tuple[float, ...] | str | None = None,
|
fillcolor: float | tuple[float, ...] | str | None = None,
|
||||||
|
@ -2803,7 +2775,7 @@ class Image:
|
||||||
im.info = self.info.copy()
|
im.info = self.info.copy()
|
||||||
if method == Transform.MESH:
|
if method == Transform.MESH:
|
||||||
# list of quads
|
# list of quads
|
||||||
for box, quad in data:
|
for box, quad in cast(Sequence[tuple[float, float]], data):
|
||||||
im.__transformer(
|
im.__transformer(
|
||||||
box, self, Transform.QUAD, quad, resample, fillcolor is None
|
box, self, Transform.QUAD, quad, resample, fillcolor is None
|
||||||
)
|
)
|
||||||
|
@ -2961,7 +2933,7 @@ class ImageTransformHandler:
|
||||||
self,
|
self,
|
||||||
size: tuple[int, int],
|
size: tuple[int, int],
|
||||||
image: Image,
|
image: Image,
|
||||||
**options: dict[str, str | int | tuple[int, ...] | list[int]],
|
**options: dict[str, str | int | tuple[int, ...] | list[int]] | int,
|
||||||
) -> Image:
|
) -> Image:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -3830,7 +3802,7 @@ class Exif(_ExifBase):
|
||||||
return self._fixup_dict(info)
|
return self._fixup_dict(info)
|
||||||
|
|
||||||
def _get_head(self):
|
def _get_head(self):
|
||||||
version = b"\x2B" if self.bigtiff else b"\x2A"
|
version = b"\x2b" if self.bigtiff else b"\x2a"
|
||||||
if self.endian == "<":
|
if self.endian == "<":
|
||||||
head = b"II" + version + b"\x00" + o32le(8)
|
head = b"II" + version + b"\x00" + o32le(8)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -118,7 +118,7 @@ class ImageDraw:
|
||||||
self.font = ImageFont.load_default()
|
self.font = ImageFont.load_default()
|
||||||
return self.font
|
return self.font
|
||||||
|
|
||||||
def _getfont(self, font_size: float | None):
|
def _getfont(self, font_size: float | None) -> FreeTypeFont | ImageFont:
|
||||||
if font_size is not None:
|
if font_size is not None:
|
||||||
from . import ImageFont
|
from . import ImageFont
|
||||||
|
|
||||||
|
@ -451,13 +451,13 @@ class ImageDraw:
|
||||||
right[3] -= r + 1
|
right[3] -= r + 1
|
||||||
self.draw.draw_rectangle(right, ink, 1)
|
self.draw.draw_rectangle(right, ink, 1)
|
||||||
|
|
||||||
def _multiline_check(self, text: str | bytes) -> bool:
|
def _multiline_check(self, text: AnyStr) -> bool:
|
||||||
split_character = "\n" if isinstance(text, str) else b"\n"
|
split_character = cast(AnyStr, "\n" if isinstance(text, str) else b"\n")
|
||||||
|
|
||||||
return split_character in text
|
return split_character in text
|
||||||
|
|
||||||
def _multiline_split(self, text: AnyStr) -> list[AnyStr]:
|
def _multiline_split(self, text: AnyStr) -> list[AnyStr]:
|
||||||
split_character = "\n" if isinstance(text, str) else b"\n"
|
split_character = cast(AnyStr, "\n" if isinstance(text, str) else b"\n")
|
||||||
|
|
||||||
return text.split(split_character)
|
return text.split(split_character)
|
||||||
|
|
||||||
|
@ -470,10 +470,10 @@ class ImageDraw:
|
||||||
|
|
||||||
def text(
|
def text(
|
||||||
self,
|
self,
|
||||||
xy: tuple[int, int],
|
xy: tuple[float, float],
|
||||||
text,
|
text: str,
|
||||||
fill=None,
|
fill=None,
|
||||||
font=None,
|
font: FreeTypeFont | ImageFont | None = None,
|
||||||
anchor=None,
|
anchor=None,
|
||||||
spacing=4,
|
spacing=4,
|
||||||
align="left",
|
align="left",
|
||||||
|
@ -527,7 +527,7 @@ class ImageDraw:
|
||||||
coord.append(int(xy[i]))
|
coord.append(int(xy[i]))
|
||||||
start.append(math.modf(xy[i])[0])
|
start.append(math.modf(xy[i])[0])
|
||||||
try:
|
try:
|
||||||
mask, offset = font.getmask2(
|
mask, offset = font.getmask2( # type: ignore[union-attr,misc]
|
||||||
text,
|
text,
|
||||||
mode,
|
mode,
|
||||||
direction=direction,
|
direction=direction,
|
||||||
|
@ -543,7 +543,7 @@ class ImageDraw:
|
||||||
coord = [coord[0] + offset[0], coord[1] + offset[1]]
|
coord = [coord[0] + offset[0], coord[1] + offset[1]]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
mask = font.getmask(
|
mask = font.getmask( # type: ignore[misc]
|
||||||
text,
|
text,
|
||||||
mode,
|
mode,
|
||||||
direction,
|
direction,
|
||||||
|
@ -592,7 +592,7 @@ class ImageDraw:
|
||||||
|
|
||||||
def multiline_text(
|
def multiline_text(
|
||||||
self,
|
self,
|
||||||
xy: tuple[int, int],
|
xy: tuple[float, float],
|
||||||
text,
|
text,
|
||||||
fill=None,
|
fill=None,
|
||||||
font=None,
|
font=None,
|
||||||
|
@ -625,7 +625,7 @@ class ImageDraw:
|
||||||
font = self._getfont(font_size)
|
font = self._getfont(font_size)
|
||||||
|
|
||||||
widths = []
|
widths = []
|
||||||
max_width = 0
|
max_width: float = 0
|
||||||
lines = self._multiline_split(text)
|
lines = self._multiline_split(text)
|
||||||
line_spacing = self._multiline_spacing(font, spacing, stroke_width)
|
line_spacing = self._multiline_spacing(font, spacing, stroke_width)
|
||||||
for line in lines:
|
for line in lines:
|
||||||
|
@ -779,7 +779,7 @@ class ImageDraw:
|
||||||
font = self._getfont(font_size)
|
font = self._getfont(font_size)
|
||||||
|
|
||||||
widths = []
|
widths = []
|
||||||
max_width = 0
|
max_width: float = 0
|
||||||
lines = self._multiline_split(text)
|
lines = self._multiline_split(text)
|
||||||
line_spacing = self._multiline_spacing(font, spacing, stroke_width)
|
line_spacing = self._multiline_spacing(font, spacing, stroke_width)
|
||||||
for line in lines:
|
for line in lines:
|
||||||
|
|
|
@ -35,11 +35,14 @@ from enum import IntEnum
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import TYPE_CHECKING, BinaryIO
|
from typing import TYPE_CHECKING, BinaryIO
|
||||||
|
|
||||||
|
from PIL import ImageFile
|
||||||
|
|
||||||
from . import Image
|
from . import Image
|
||||||
from ._typing import StrOrBytesPath
|
from ._typing import StrOrBytesPath
|
||||||
from ._util import is_directory, is_path
|
from ._util import is_directory, is_path
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from ._imaging import ImagingFont
|
||||||
from ._imagingft import Font
|
from ._imagingft import Font
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,11 +87,11 @@ def _string_length_check(text: str | bytes) -> None:
|
||||||
class ImageFont:
|
class ImageFont:
|
||||||
"""PIL font wrapper"""
|
"""PIL font wrapper"""
|
||||||
|
|
||||||
font: Font
|
font: ImagingFont
|
||||||
|
|
||||||
def _load_pilfont(self, filename: str) -> None:
|
def _load_pilfont(self, filename: str) -> None:
|
||||||
with open(filename, "rb") as fp:
|
with open(filename, "rb") as fp:
|
||||||
image = None
|
image: ImageFile.ImageFile | None = None
|
||||||
for ext in (".png", ".gif", ".pbm"):
|
for ext in (".png", ".gif", ".pbm"):
|
||||||
if image:
|
if image:
|
||||||
image.close()
|
image.close()
|
||||||
|
@ -198,6 +201,8 @@ class ImageFont:
|
||||||
class FreeTypeFont:
|
class FreeTypeFont:
|
||||||
"""FreeType font wrapper (requires _imagingft service)"""
|
"""FreeType font wrapper (requires _imagingft service)"""
|
||||||
|
|
||||||
|
font: Font
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
font: StrOrBytesPath | BinaryIO | None = None,
|
font: StrOrBytesPath | BinaryIO | None = None,
|
||||||
|
@ -261,7 +266,7 @@ class FreeTypeFont:
|
||||||
path, size, index, encoding, layout_engine = state
|
path, size, index, encoding, layout_engine = state
|
||||||
self.__init__(path, size, index, encoding, layout_engine)
|
self.__init__(path, size, index, encoding, layout_engine)
|
||||||
|
|
||||||
def getname(self) -> tuple[str, str]:
|
def getname(self) -> tuple[str | None, str | None]:
|
||||||
"""
|
"""
|
||||||
:return: A tuple of the font family (e.g. Helvetica) and the font style
|
:return: A tuple of the font family (e.g. Helvetica) and the font style
|
||||||
(e.g. Bold)
|
(e.g. Bold)
|
||||||
|
@ -876,6 +881,7 @@ def load_path(filename: str | bytes) -> ImageFont:
|
||||||
"""
|
"""
|
||||||
for directory in sys.path:
|
for directory in sys.path:
|
||||||
if is_directory(directory):
|
if is_directory(directory):
|
||||||
|
assert isinstance(directory, str)
|
||||||
if not isinstance(filename, str):
|
if not isinstance(filename, str):
|
||||||
filename = filename.decode("utf-8")
|
filename = filename.decode("utf-8")
|
||||||
try:
|
try:
|
||||||
|
@ -900,6 +906,7 @@ def load_default(size: float | None = None) -> FreeTypeFont | ImageFont:
|
||||||
|
|
||||||
:return: A font object.
|
:return: A font object.
|
||||||
"""
|
"""
|
||||||
|
f: FreeTypeFont | ImageFont
|
||||||
if core.__class__.__name__ == "module" or size is not None:
|
if core.__class__.__name__ == "module" or size is not None:
|
||||||
f = truetype(
|
f = truetype(
|
||||||
BytesIO(
|
BytesIO(
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#
|
#
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Sequence
|
from typing import Any, Sequence
|
||||||
|
|
||||||
from . import Image
|
from . import Image
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class Transform(Image.ImageTransformHandler):
|
||||||
self,
|
self,
|
||||||
size: tuple[int, int],
|
size: tuple[int, int],
|
||||||
image: Image.Image,
|
image: Image.Image,
|
||||||
**options: dict[str, str | int | tuple[int, ...] | list[int]],
|
**options: Any,
|
||||||
) -> Image.Image:
|
) -> Image.Image:
|
||||||
"""Perform the transform. Called from :py:meth:`.Image.transform`."""
|
"""Perform the transform. Called from :py:meth:`.Image.transform`."""
|
||||||
# can be overridden
|
# can be overridden
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from typing_extensions import Buffer
|
||||||
|
|
||||||
|
class ImagingCore:
|
||||||
|
def __getattr__(self, name: str) -> Any: ...
|
||||||
|
|
||||||
|
class ImagingFont:
|
||||||
|
def __getattr__(self, name: str) -> Any: ...
|
||||||
|
|
||||||
|
class ImagingDraw:
|
||||||
|
def __getattr__(self, name: str) -> Any: ...
|
||||||
|
|
||||||
|
class PixelAccess:
|
||||||
|
def __getattr__(self, name: str) -> Any: ...
|
||||||
|
|
||||||
|
def font(image, glyphdata: Buffer) -> ImagingFont: ...
|
||||||
def __getattr__(name: str) -> Any: ...
|
def __getattr__(name: str) -> Any: ...
|
||||||
|
|
Loading…
Reference in New Issue
Block a user