Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pypdf/_font.py: 75%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from dataclasses import dataclass, field
3from pypdf.generic import DictionaryObject
6@dataclass(frozen=True)
7class FontDescriptor:
8 """
9 Represents the FontDescriptor dictionary as defined in the PDF specification.
10 This contains both descriptive and metric information.
12 The defaults are derived from the mean values of the 14 core fonts, rounded
13 to 100.
14 """
16 name: str = "Unknown"
17 family: str = "Unknown"
18 weight: str = "Unknown"
20 ascent: float = 700.0
21 descent: float = -200.0
22 cap_height: float = 600.0
23 x_height: float = 500.0
24 italic_angle: float = 0.0 # Non-italic
25 flags: int = 32 # Non-serif, non-symbolic, not fixed width
26 bbox: tuple[float, float, float, float] = field(default_factory=lambda: (-100.0, -200.0, 1000.0, 900.0))
28 character_widths: dict[str, int] = field(default_factory=dict)
30 @classmethod
31 def from_font_resource(cls, pdf_font_dict: DictionaryObject) -> "FontDescriptor":
32 from pypdf._codecs.core_fontmetrics import CORE_FONT_METRICS # noqa: PLC0415
33 # Prioritize information from the PDF font dictionary
34 font_name = pdf_font_dict.get("/BaseFont", "Unknown").removeprefix("/")
35 if font_name in CORE_FONT_METRICS:
36 return CORE_FONT_METRICS[font_name]
37 return cls(name=font_name)
39 def text_width(self, text: str) -> float:
40 """Sum of character widths specified in PDF font for the supplied text."""
41 return sum(
42 [self.character_widths.get(char, self.character_widths.get("default", 0)) for char in text], 0.0
43 )