3333import warnings
3434from enum import IntEnum
3535from io import BytesIO
36- from typing import TYPE_CHECKING , BinaryIO
36+ from typing import IO , TYPE_CHECKING , Any , BinaryIO
3737
3838from . import Image
3939from ._typing import StrOrBytesPath
40- from ._util import is_directory , is_path
40+ from ._util import is_path
4141
4242if TYPE_CHECKING :
4343 from . import ImageFile
@@ -61,7 +61,7 @@ class Layout(IntEnum):
6161 core = DeferredError .new (ex )
6262
6363
64- def _string_length_check (text : str ) -> None :
64+ def _string_length_check (text : str | bytes | bytearray ) -> None :
6565 if MAX_STRING_LENGTH is not None and len (text ) > MAX_STRING_LENGTH :
6666 msg = "too many characters in string"
6767 raise ValueError (msg )
@@ -113,7 +113,7 @@ def _load_pilfont(self, filename: str) -> None:
113113 self ._load_pilfont_data (fp , image )
114114 image .close ()
115115
116- def _load_pilfont_data (self , file , image ) :
116+ def _load_pilfont_data (self , file : IO [ bytes ] , image : Image . Image ) -> None :
117117 # read PILfont header
118118 if file .readline () != b"PILfont\n " :
119119 msg = "Not a PILfont file"
@@ -161,7 +161,7 @@ def getmask(self, text, mode="", *args, **kwargs):
161161 return self .font .getmask (text , mode )
162162
163163 def getbbox (
164- self , text : str , * args : object , ** kwargs : object
164+ self , text : str | bytes | bytearray , * args : Any , ** kwargs : Any
165165 ) -> tuple [int , int , int , int ]:
166166 """
167167 Returns bounding box (in pixels) of given text.
@@ -180,7 +180,9 @@ def getbbox(
180180 width , height = self .font .getsize (text )
181181 return 0 , 0 , width , height
182182
183- def getlength (self , text : str , * args : object , ** kwargs : object ) -> int :
183+ def getlength (
184+ self , text : str | bytes | bytearray , * args : Any , ** kwargs : Any
185+ ) -> int :
184186 """
185187 Returns length (in pixels) of given text.
186188 This is the amount by which following text should be offset.
@@ -357,13 +359,13 @@ def getlength(
357359 def getbbox (
358360 self ,
359361 text : str ,
360- mode = "" ,
361- direction = None ,
362- features = None ,
363- language = None ,
364- stroke_width = 0 ,
365- anchor = None ,
366- ) -> tuple [int , int , int , int ]:
362+ mode : str = "" ,
363+ direction : str | None = None ,
364+ features : str | None = None ,
365+ language : str | None = None ,
366+ stroke_width : float = 0 ,
367+ anchor : str | None = None ,
368+ ) -> tuple [float , float , float , float ]:
367369 """
368370 Returns bounding box (in pixels) of given text relative to given anchor
369371 when rendered in font with provided direction, features, and language.
@@ -513,7 +515,7 @@ def getmask(
513515
514516 def getmask2 (
515517 self ,
516- text ,
518+ text : str ,
517519 mode = "" ,
518520 direction = None ,
519521 features = None ,
@@ -641,7 +643,7 @@ def font_variant(
641643 layout_engine = layout_engine or self .layout_engine ,
642644 )
643645
644- def get_variation_names (self ):
646+ def get_variation_names (self ) -> list [ bytes ] :
645647 """
646648 :returns: A list of the named styles in a variation font.
647649 :exception OSError: If the font is not a variation font.
@@ -683,10 +685,11 @@ def get_variation_axes(self):
683685 msg = "FreeType 2.9.1 or greater is required"
684686 raise NotImplementedError (msg ) from e
685687 for axis in axes :
686- axis ["name" ] = axis ["name" ].replace (b"\x00 " , b"" )
688+ if axis ["name" ]:
689+ axis ["name" ] = axis ["name" ].replace (b"\x00 " , b"" )
687690 return axes
688691
689- def set_variation_by_axes (self , axes ) :
692+ def set_variation_by_axes (self , axes : list [ float ]) -> None :
690693 """
691694 :param axes: A list of values for each axis.
692695 :exception OSError: If the font is not a variation font.
@@ -731,7 +734,7 @@ def getbbox(self, text, *args, **kwargs):
731734 return 0 , 0 , height , width
732735 return 0 , 0 , width , height
733736
734- def getlength (self , text , * args , ** kwargs ):
737+ def getlength (self , text : str , * args , ** kwargs ) -> float :
735738 if self .orientation in (Image .Transpose .ROTATE_90 , Image .Transpose .ROTATE_270 ):
736739 msg = "text length is undefined for text rotated by 90 or 270 degrees"
737740 raise ValueError (msg )
@@ -878,15 +881,13 @@ def load_path(filename: str | bytes) -> ImageFont:
878881 :return: A font object.
879882 :exception OSError: If the file could not be read.
880883 """
884+ if not isinstance (filename , str ):
885+ filename = filename .decode ("utf-8" )
881886 for directory in sys .path :
882- if is_directory (directory ):
883- assert isinstance (directory , str )
884- if not isinstance (filename , str ):
885- filename = filename .decode ("utf-8" )
886- try :
887- return load (os .path .join (directory , filename ))
888- except OSError :
889- pass
887+ try :
888+ return load (os .path .join (directory , filename ))
889+ except OSError :
890+ pass
890891 msg = "cannot find font file"
891892 raise OSError (msg )
892893
0 commit comments