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

24 statements  

1from dataclasses import dataclass, field 

2 

3from pypdf.generic import DictionaryObject 

4 

5 

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. 

11 

12 The defaults are derived from the mean values of the 14 core fonts, rounded 

13 to 100. 

14 """ 

15 

16 name: str = "Unknown" 

17 family: str = "Unknown" 

18 weight: str = "Unknown" 

19 

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)) 

27 

28 character_widths: dict[str, int] = field(default_factory=dict) 

29 

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) 

38 

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 )