11import re
22from dataclasses import dataclass
33from enum import IntEnum
4+ from io import BytesIO
45from typing import Any , Optional , Union , cast
56
67from .._codecs import fill_from_encoding
78from .._codecs .core_font_metrics import CORE_FONT_METRICS
8- from .._font import Font
9+ from .._font import HAS_FONTTOOLS , Font
910from .._utils import logger_warning
1011from ..constants import AnnotationDictionaryAttributes , BorderStyles , FieldDictionaryAttributes
1112from ..generic import (
@@ -374,6 +375,17 @@ def __init__(
374375 except UnicodeEncodeError :
375376 encodable = False
376377
378+ if not encodable :
379+ # If we have a font file, we can try to produce a new font resource with an encoding
380+ # that does include the necessary characters.
381+ if font .font_descriptor .font_file and HAS_FONTTOOLS and font .sub_type == "TrueType" :
382+ new_font = font .from_truetype_font_file (BytesIO (font .font_descriptor .font_file .get_data ()))
383+ if font :
384+ font = new_font
385+ font_resource = font .as_font_resource ()
386+ font_name = f"/{ font .name } "
387+ encodable = True
388+
377389 if not encodable :
378390 logger_warning (
379391 f"Text string '{ text } ' contains characters not supported by font encoding. "
@@ -384,9 +396,9 @@ def __init__(
384396
385397 font_glyph_byte_map : dict [str , bytes ]
386398 if isinstance (font .encoding , str ):
387- font_glyph_byte_map = {
388- v : k . encode ( font . encoding ) for k , v in font .character_map .items ()
389- }
399+ font_glyph_byte_map = {}
400+ for key , value in font .character_map .items ():
401+ font_glyph_byte_map [ value ] = key . encode ( font . encoding )
390402 else :
391403 font_glyph_byte_map = {v : bytes ((k ,)) for k , v in font .encoding .items ()}
392404 font_encoding_rev = {v : bytes ((k ,)) for k , v in font .encoding .items ()}
0 commit comments