Skip to content

Commit 175a542

Browse files
committed
ENH: AppearanceStream: Generate new font resource for unicode
This enables generating a new unicode font resource in case of text widget values that cannot be encoded with existing font resources.
1 parent 45ca4d7 commit 175a542

1 file changed

Lines changed: 16 additions & 4 deletions

File tree

pypdf/generic/_appearance_stream.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import re
22
from dataclasses import dataclass
33
from enum import IntEnum
4+
from io import BytesIO
45
from typing import Any, Optional, Union, cast
56

67
from .._codecs import fill_from_encoding
78
from .._codecs.core_font_metrics import CORE_FONT_METRICS
8-
from .._font import Font
9+
from .._font import HAS_FONTTOOLS, Font
910
from .._utils import logger_warning
1011
from ..constants import AnnotationDictionaryAttributes, BorderStyles, FieldDictionaryAttributes
1112
from ..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

Comments
 (0)