This commit is contained in:
Andrew Murray 2026-05-16 18:28:16 +10:00 committed by GitHub
commit 8ce66ffdd1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 57 additions and 58 deletions

View File

@ -65,15 +65,21 @@ Functions
Methods
-------
.. autoclass:: PIL.ImageFont.BaseImageFont
:members:
.. autoclass:: PIL.ImageFont.ImageFont
:members:
:show-inheritance:
.. autoclass:: PIL.ImageFont.FreeTypeFont
:members:
:show-inheritance:
.. autoclass:: PIL.ImageFont.TransposedFont
:members:
:undoc-members:
:show-inheritance:
Constants
---------

View File

@ -36,7 +36,7 @@ import struct
from collections.abc import Sequence
from typing import cast
from . import Image, ImageColor, ImageText
from . import Image, ImageColor, ImageFont, ImageText
TYPE_CHECKING = False
if TYPE_CHECKING:
@ -44,7 +44,7 @@ if TYPE_CHECKING:
from types import ModuleType
from typing import Any, AnyStr
from . import ImageDraw2, ImageFont
from . import ImageDraw2
from ._typing import Coords, _Ink
# experimental access to the outline API
@ -59,9 +59,7 @@ directly.
class ImageDraw:
font: (
ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont | None
) = None
font: ImageFont.BaseImageFont | None = None
def __init__(self, im: Image.Image, mode: str | None = None) -> None:
"""
@ -105,7 +103,7 @@ class ImageDraw:
def getfont(
self,
) -> ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont:
) -> ImageFont.BaseImageFont:
"""
Get the current default font.
@ -130,9 +128,7 @@ class ImageDraw:
self.font = ImageFont.load_default()
return self.font
def _getfont(
self, font_size: float | None
) -> ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont:
def _getfont(self, font_size: float | None) -> ImageFont.BaseImageFont:
if font_size is not None:
from . import ImageFont
@ -540,12 +536,7 @@ class ImageDraw:
xy: tuple[float, float],
text: AnyStr | ImageText.Text[AnyStr],
fill: _Ink | None = None,
font: (
ImageFont.ImageFont
| ImageFont.FreeTypeFont
| ImageFont.TransposedFont
| None
) = None,
font: ImageFont.BaseImageFont | None = None,
anchor: str | None = None,
spacing: float = 4,
align: str = "left",
@ -600,26 +591,26 @@ class ImageDraw:
x = int(line.x)
y = int(line.y)
start = (math.modf(line.x)[0], math.modf(line.y)[0])
try:
mask, offset = image_text.font.getmask2( # type: ignore[union-attr,misc]
if isinstance(image_text.font, ImageFont.FreeTypeFont):
mask, offset = image_text.font.getmask2(
line.text,
mode,
direction=direction,
features=features,
language=language,
stroke_width=stroke_width,
direction,
features,
language,
stroke_width,
line.anchor,
ink,
start,
stroke_filled=True,
anchor=line.anchor,
ink=ink,
start=start,
*args,
**kwargs,
)
x += offset[0]
y += offset[1]
except AttributeError:
else:
try:
mask = image_text.font.getmask( # type: ignore[misc]
mask = image_text.font.getmask(
line.text,
mode,
direction,
@ -664,12 +655,7 @@ class ImageDraw:
xy: tuple[float, float],
text: AnyStr,
fill: _Ink | None = None,
font: (
ImageFont.ImageFont
| ImageFont.FreeTypeFont
| ImageFont.TransposedFont
| None
) = None,
font: ImageFont.BaseImageFont | None = None,
anchor: str | None = None,
spacing: float = 4,
align: str = "left",
@ -702,12 +688,7 @@ class ImageDraw:
def textlength(
self,
text: AnyStr,
font: (
ImageFont.ImageFont
| ImageFont.FreeTypeFont
| ImageFont.TransposedFont
| None
) = None,
font: ImageFont.BaseImageFont | None = None,
direction: str | None = None,
features: list[str] | None = None,
language: str | None = None,
@ -734,12 +715,7 @@ class ImageDraw:
self,
xy: tuple[float, float],
text: AnyStr,
font: (
ImageFont.ImageFont
| ImageFont.FreeTypeFont
| ImageFont.TransposedFont
| None
) = None,
font: ImageFont.BaseImageFont | None = None,
anchor: str | None = None,
spacing: float = 4,
align: str = "left",
@ -767,12 +743,7 @@ class ImageDraw:
self,
xy: tuple[float, float],
text: AnyStr,
font: (
ImageFont.ImageFont
| ImageFont.FreeTypeFont
| ImageFont.TransposedFont
| None
) = None,
font: ImageFont.BaseImageFont | None = None,
anchor: str | None = None,
spacing: float = 4,
align: str = "left",

View File

@ -27,6 +27,7 @@
from __future__ import annotations
import abc
import base64
import os
import sys
@ -91,7 +92,27 @@ def _string_length_check(text: str | bytes | bytearray) -> None:
# --------------------------------------------------------------------
class ImageFont:
class BaseImageFont(abc.ABC):
"""Used by ImageDraw and ImageText"""
@abc.abstractmethod
def getbbox(
self, text: str | bytes | bytearray, *args: Any, **kwargs: Any
) -> tuple[float, float, float, float]:
pass
@abc.abstractmethod
def getmask(
self, text: str | bytes, mode: str = "", *args: Any, **kwargs: Any
) -> Image.core.ImagingCore:
pass
@abc.abstractmethod
def getlength(self, text: str | bytes, *args: Any, **kwargs: Any) -> float:
pass
class ImageFont(BaseImageFont):
"""PIL font wrapper"""
font: ImagingFont
@ -215,7 +236,7 @@ class ImageFont:
# <b>truetype</b> factory function to create font objects.
class FreeTypeFont:
class FreeTypeFont(BaseImageFont):
"""FreeType font wrapper (requires _imagingft service)"""
font: Font
@ -723,7 +744,7 @@ class FreeTypeFont:
self.font.setvaraxes(axes)
class TransposedFont:
class TransposedFont(BaseImageFont):
"""Wrapper for writing rotated or mirrored text"""
def __init__(

View File

@ -7,8 +7,6 @@ from typing import AnyStr, Generic, NamedTuple
from . import ImageFont
from ._typing import _Ink
Font = ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont
class _Line(NamedTuple):
x: float
@ -27,7 +25,7 @@ class _Wrap(Generic[AnyStr]):
text: Text[AnyStr],
width: int,
height: int | None = None,
font: Font | None = None,
font: ImageFont.BaseImageFont | None = None,
) -> None:
self.text: Text[AnyStr] = text
self.width = width
@ -97,7 +95,7 @@ class Text(Generic[AnyStr]):
def __init__(
self,
text: AnyStr,
font: Font | None = None,
font: ImageFont.BaseImageFont | None = None,
mode: str = "RGB",
spacing: float = 4,
direction: str | None = None,
@ -449,7 +447,10 @@ class Text(Generic[AnyStr]):
return parts
def _get_bbox(
self, text: str | bytes, font: Font | None = None, anchor: str | None = None
self,
text: str | bytes,
font: ImageFont.BaseImageFont | None = None,
anchor: str | None = None,
) -> tuple[float, float, float, float]:
return (font or self.font).getbbox(
text,