Merge pull request #7578 from radarhere/font

Handle pathlib.Path in FreeTypeFont
This commit is contained in:
Andrew Murray 2023-12-06 12:09:16 +11:00 committed by GitHub
commit e43dd6610d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 14 deletions

View File

@ -4,6 +4,7 @@ import re
import shutil import shutil
import sys import sys
from io import BytesIO from io import BytesIO
from pathlib import Path
import pytest import pytest
from packaging.version import parse as parse_version from packaging.version import parse as parse_version
@ -76,8 +77,9 @@ def _render(font, layout_engine):
return img return img
def test_font_with_name(layout_engine): @pytest.mark.parametrize("font", (FONT_PATH, Path(FONT_PATH)))
_render(FONT_PATH, layout_engine) def test_font_with_name(layout_engine, font):
_render(font, layout_engine)
def test_font_with_filelike(layout_engine): def test_font_with_filelike(layout_engine):

View File

@ -70,12 +70,14 @@ Methods
Constants Constants
--------- ---------
.. data:: PIL.ImageFont.Layout.BASIC .. class:: Layout
.. py:attribute:: BASIC
Use basic text layout for TrueType font. Use basic text layout for TrueType font.
Advanced features such as text direction are not supported. Advanced features such as text direction are not supported.
.. data:: PIL.ImageFont.Layout.RAQM .. py:attribute:: RAQM
Use Raqm text layout for TrueType font. Use Raqm text layout for TrueType font.
Advanced features are supported. Advanced features are supported.
@ -83,9 +85,6 @@ Constants
Requires Raqm, you can check support using Requires Raqm, you can check support using
:py:func:`PIL.features.check_feature` with ``feature="raqm"``. :py:func:`PIL.features.check_feature` with ``feature="raqm"``.
Constants
---------
.. data:: MAX_STRING_LENGTH .. data:: MAX_STRING_LENGTH
Set to 1,000,000, to protect against potential DOS attacks. Pillow will Set to 1,000,000, to protect against potential DOS attacks. Pillow will

View File

@ -25,12 +25,16 @@
# See the README file for information on usage and redistribution. # See the README file for information on usage and redistribution.
# #
from __future__ import annotations
import base64 import base64
import os import os
import sys import sys
import warnings import warnings
from enum import IntEnum from enum import IntEnum
from io import BytesIO from io import BytesIO
from pathlib import Path
from typing import IO
from . import Image from . import Image
from ._util import is_directory, is_path from ._util import is_directory, is_path
@ -185,7 +189,14 @@ class ImageFont:
class FreeTypeFont: class FreeTypeFont:
"""FreeType font wrapper (requires _imagingft service)""" """FreeType font wrapper (requires _imagingft service)"""
def __init__(self, font=None, size=10, index=0, encoding="", layout_engine=None): def __init__(
self,
font: bytes | str | Path | IO | None = None,
size: float = 10,
index: int = 0,
encoding: str = "",
layout_engine: Layout | None = None,
) -> None:
# FIXME: use service provider instead # FIXME: use service provider instead
if size <= 0: if size <= 0:
@ -217,6 +228,8 @@ class FreeTypeFont:
) )
if is_path(font): if is_path(font):
if isinstance(font, Path):
font = str(font)
if sys.platform == "win32": if sys.platform == "win32":
font_bytes_path = font if isinstance(font, bytes) else font.encode() font_bytes_path = font if isinstance(font, bytes) else font.encode()
try: try:
@ -779,7 +792,7 @@ def truetype(font=None, size=10, index=0, encoding="", layout_engine=None):
This specifies the character set to use. It does not alter the This specifies the character set to use. It does not alter the
encoding of any text provided in subsequent operations. encoding of any text provided in subsequent operations.
:param layout_engine: Which layout engine to use, if available: :param layout_engine: Which layout engine to use, if available:
:data:`.ImageFont.Layout.BASIC` or :data:`.ImageFont.Layout.RAQM`. :attr:`.ImageFont.Layout.BASIC` or :attr:`.ImageFont.Layout.RAQM`.
If it is available, Raqm layout will be used by default. If it is available, Raqm layout will be used by default.
Otherwise, basic layout will be used. Otherwise, basic layout will be used.