Skip to content

Commit 3171cb4

Browse files
authored
Bump fpdf2 to 2.7.7 (#11149)
Closes: #11145
1 parent 0e5277c commit 3171cb4

15 files changed

+300
-59
lines changed

stubs/fpdf2/METADATA.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version = "2.7.6"
1+
version = "2.7.7"
22
upstream_repository = "https://github.com/PyFPDF/fpdf2"
33
requires = ["types-Pillow>=9.2.0"]
44

stubs/fpdf2/fpdf/__init__.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from pathlib import Path
22

33
from .enums import Align as Align, TextMode as TextMode, XPos as XPos, YPos as YPos
4+
from .fonts import FontFace as FontFace
45
from .fpdf import FPDF as FPDF, FPDFException as FPDFException, TitleStyle as TitleStyle
56
from .html import HTML2FPDF as HTML2FPDF, HTMLMixin as HTMLMixin
67
from .prefs import ViewerPreferences as ViewerPreferences
@@ -16,6 +17,7 @@ __all__ = [
1617
"__license__",
1718
"FPDF",
1819
"FPDFException",
20+
"FontFace",
1921
"Align",
2022
"TextMode",
2123
"XPos",

stubs/fpdf2/fpdf/annotations.pyi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ from .actions import Action
66
from .enums import AnnotationFlag, AnnotationName, FileAttachmentAnnotationName
77
from .syntax import Destination, Name, PDFContentStream, PDFObject
88

9-
DEFAULT_ANNOT_FLAGS: Incomplete
9+
DEFAULT_ANNOT_FLAGS: tuple[AnnotationFlag, ...]
1010

1111
class AnnotationMixin:
1212
type: Name
@@ -27,6 +27,7 @@ class AnnotationMixin:
2727
name: AnnotationName | FileAttachmentAnnotationName | None
2828
ink_list: str | None
2929
f_s: str | None
30+
d_a: str | None
3031
def __init__(
3132
self,
3233
subtype: str,
@@ -48,6 +49,7 @@ class AnnotationMixin:
4849
file_spec: str | None = None,
4950
field_type: str | None = None,
5051
value: Incomplete | None = None,
52+
default_appearance: str | None = None,
5153
) -> None: ...
5254

5355
class PDFAnnotation(AnnotationMixin, PDFObject): ...

stubs/fpdf2/fpdf/drawing.pyi

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import decimal
22
from _typeshed import Incomplete
33
from collections import OrderedDict
4-
from collections.abc import Callable, Generator, Iterator
4+
from collections.abc import Callable, Generator, Iterator, Sequence
55
from contextlib import contextmanager
66
from re import Pattern
7-
from typing import Any, ClassVar, NamedTuple, TypeVar
8-
from typing_extensions import Self, TypeAlias
7+
from typing import Any, ClassVar, NamedTuple, TypeVar, overload
8+
from typing_extensions import Literal, Self, TypeAlias
99

1010
from .syntax import Name, Raw
1111

@@ -70,6 +70,14 @@ class DeviceCMYK(_DeviceCMYKBase):
7070

7171
def rgb8(r, g, b, a: Incomplete | None = None) -> DeviceRGB: ...
7272
def gray8(g, a: Incomplete | None = None) -> DeviceGray: ...
73+
@overload
74+
def convert_to_device_color(r: DeviceGray, g: int = -1, b: int = -1) -> DeviceGray: ...
75+
@overload
76+
def convert_to_device_color(r: DeviceRGB, g: int = -1, b: int = -1) -> DeviceRGB: ...
77+
@overload
78+
def convert_to_device_color(r: int, g: Literal[-1] = -1, b: Literal[-1] = -1) -> DeviceGray: ...
79+
@overload
80+
def convert_to_device_color(r: Sequence[int] | int, g: int, b: int) -> DeviceGray | DeviceRGB: ...
7381
def cmyk8(c, m, y, k, a: Incomplete | None = None) -> DeviceCMYK: ...
7482
def color_from_hex_string(hexstr) -> DeviceRGB: ...
7583
def color_from_rgb_string(rgbstr) -> DeviceRGB: ...

stubs/fpdf2/fpdf/enums.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class TableCellFillMode(CoerciveEnum):
7070
ROWS: str
7171
COLUMNS: str
7272

73+
def should_fill_cell(self, i: int, j: int) -> bool: ...
74+
7375
class RenderStyle(CoerciveEnum):
7476
D: str
7577
F: str

stubs/fpdf2/fpdf/fonts.pyi

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import dataclasses
22
from _typeshed import Incomplete
33
from collections.abc import Generator
44
from dataclasses import dataclass
5+
from typing import overload
56

67
from .drawing import DeviceGray, DeviceRGB, Number
78
from .enums import TextEmphasis
@@ -12,8 +13,8 @@ class FontFace:
1213
family: str | None
1314
emphasis: TextEmphasis | None
1415
size_pt: int | None
15-
color: int | tuple[Number, Number, Number] | DeviceGray | DeviceRGB | None
16-
fill_color: int | tuple[Number, Number, Number] | DeviceGray | DeviceRGB | None
16+
color: DeviceGray | DeviceRGB | None
17+
fill_color: DeviceGray | DeviceRGB | None
1718

1819
def __init__(
1920
self,
@@ -26,6 +27,13 @@ class FontFace:
2627

2728
replace = dataclasses.replace
2829

30+
@overload
31+
@staticmethod
32+
def combine(default_style: None, override_style: None) -> None: ... # type: ignore[misc]
33+
@overload
34+
@staticmethod
35+
def combine(default_style: FontFace | None, override_style: FontFace | None) -> FontFace: ...
36+
2937
class _FontMixin:
3038
i: int
3139
type: str

stubs/fpdf2/fpdf/fpdf.pyi

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ from io import BytesIO
66
from pathlib import PurePath
77
from re import Pattern
88
from typing import Any, ClassVar, NamedTuple, overload
9-
from typing_extensions import Literal, TypeAlias
9+
from typing_extensions import Final, Literal, TypeAlias, deprecated
1010

1111
from fpdf import ViewerPreferences
1212
from PIL import Image
@@ -35,30 +35,40 @@ from .errors import FPDFException as FPDFException
3535
from .fonts import FontFace
3636
from .graphics_state import GraphicsStateMixin
3737
from .html import HTML2FPDF
38+
from .image_datastructures import (
39+
ImageCache,
40+
ImageInfo as ImageInfo,
41+
RasterImageInfo as RasterImageInfo,
42+
VectorImageInfo as VectorImageInfo,
43+
_AlignLiteral,
44+
)
3845
from .output import OutputProducer, PDFPage
3946
from .recorder import FPDFRecorder
4047
from .structure_tree import StructureTreeBuilder
4148
from .syntax import DestinationXYZ
4249
from .table import Table
4350
from .util import _Unit
4451

45-
__all__ = ["FPDF", "XPos", "YPos", "get_page_format", "ImageInfo", "TextMode", "TitleStyle", "PAGE_FORMATS"]
52+
__all__ = [
53+
"FPDF",
54+
"XPos",
55+
"YPos",
56+
"get_page_format",
57+
"ImageInfo",
58+
"RasterImageInfo",
59+
"VectorImageInfo",
60+
"TextMode",
61+
"TitleStyle",
62+
"PAGE_FORMATS",
63+
]
4664

4765
_Orientation: TypeAlias = Literal["", "portrait", "p", "P", "landscape", "l", "L"]
4866
_Format: TypeAlias = Literal["", "a3", "A3", "a4", "A4", "a5", "A5", "letter", "Letter", "legal", "Legal"]
4967
_FontStyle: TypeAlias = Literal["", "B", "I"]
5068
_FontStyles: TypeAlias = Literal["", "B", "I", "U", "BU", "UB", "BI", "IB", "IU", "UI", "BIU", "BUI", "IBU", "IUB", "UBI", "UIB"]
51-
PAGE_FORMATS: dict[_Format, tuple[float, float]]
5269

53-
class ImageInfo(dict[str, Any]):
54-
@property
55-
def width(self) -> int: ...
56-
@property
57-
def height(self) -> int: ...
58-
@property
59-
def rendered_width(self) -> int: ...
60-
@property
61-
def rendered_height(self) -> int: ...
70+
FPDF_VERSION: Final[str]
71+
PAGE_FORMATS: dict[_Format, tuple[float, float]]
6272

6373
class TitleStyle(FontFace):
6474
t_margin: int | None
@@ -87,7 +97,6 @@ def get_page_format(format: _Format | tuple[float, float], k: float | None = Non
8797

8898
# TODO: TypedDicts
8999
_Font: TypeAlias = dict[str, Any]
90-
_Image: TypeAlias = dict[str, Any]
91100

92101
class FPDF(GraphicsStateMixin):
93102
MARKDOWN_BOLD_MARKER: ClassVar[str]
@@ -102,15 +111,14 @@ class FPDF(GraphicsStateMixin):
102111
page: int
103112
pages: dict[int, PDFPage]
104113
fonts: dict[str, _Font]
105-
images: dict[str, _Image]
106114
links: dict[int, DestinationXYZ]
107115
embedded_files: list[PDFEmbeddedFile]
116+
image_cache: ImageCache
108117

109118
in_footer: bool
110119
str_alias_nb_pages: str
111120

112121
xmp_metadata: str | None
113-
image_filter: str
114122
page_duration: int
115123
page_transition: Incomplete | None
116124
allow_images_transparency: bool
@@ -148,6 +156,8 @@ class FPDF(GraphicsStateMixin):
148156
w: float
149157
h: float
150158

159+
text_shaping: dict[str, Incomplete] | None # TODO: TypedDict
160+
151161
def __init__(
152162
self,
153163
orientation: _Orientation = "portrait",
@@ -371,7 +381,16 @@ class FPDF(GraphicsStateMixin):
371381
h: float = 1,
372382
name: AnnotationName | str | None = None,
373383
flags: tuple[AnnotationFlag, ...] | tuple[str, ...] = ...,
374-
) -> None: ...
384+
) -> AnnotationDict: ...
385+
def free_text_annotation(
386+
self,
387+
text: str,
388+
x: float | None = None,
389+
y: float | None = None,
390+
w: float | None = None,
391+
h: float | None = None,
392+
flags: tuple[AnnotationFlag, ...] | tuple[str, ...] = ...,
393+
) -> AnnotationDict: ...
375394
def add_action(self, action, x: float, y: float, w: float, h: float) -> None: ...
376395
def highlight(
377396
self,
@@ -466,10 +485,12 @@ class FPDF(GraphicsStateMixin):
466485
def text_columns(
467486
self,
468487
text: str | None = None,
488+
img: str | None = None,
489+
img_fill_width: bool = False,
469490
ncols: int = 1,
470491
gutter: float = 10,
471492
balance: bool = False,
472-
text_align: Align | str = "LEFT",
493+
text_align: Align | _AlignLiteral = "LEFT",
473494
line_height: float = 1,
474495
l_margin: float | None = None,
475496
r_margin: float | None = None,
@@ -490,7 +511,8 @@ class FPDF(GraphicsStateMixin):
490511
alt_text: str | None = None,
491512
dims: tuple[float, float] | None = None,
492513
keep_aspect_ratio: bool = False,
493-
) -> _Image: ...
514+
) -> RasterImageInfo | VectorImageInfo: ...
515+
@deprecated("Deprecated since 2.7.7; use fpdf.image_parsing.preload_image() instead")
494516
def preload_image(
495517
self, name: str | Image.Image | BytesIO, dims: tuple[float, float] | None = None
496518
) -> tuple[str, Any, ImageInfo]: ...

stubs/fpdf2/fpdf/graphics_state.pyi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,8 @@ class GraphicsStateMixin:
102102
def denom_lift(self): ...
103103
@denom_lift.setter
104104
def denom_lift(self, v) -> None: ...
105+
@property
106+
def text_shaping(self): ...
107+
@text_shaping.setter
108+
def text_shaping(self, v) -> None: ...
105109
def font_face(self) -> FontFace: ...
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from _typeshed import Incomplete
2+
from dataclasses import dataclass
3+
from typing import Any
4+
from typing_extensions import Literal, TypeAlias
5+
6+
from fpdf.enums import Align
7+
from fpdf.fpdf import FPDF
8+
9+
from .image_parsing import _ImageFilter
10+
11+
_AlignLiteral: TypeAlias = Literal[
12+
"",
13+
"CENTER",
14+
"X_CENTER",
15+
"LEFT",
16+
"RIGHT",
17+
"JUSTIFY",
18+
"center",
19+
"x_center",
20+
"left",
21+
"right",
22+
"justify",
23+
"C",
24+
"X",
25+
"L",
26+
"R",
27+
"J",
28+
"c",
29+
"x",
30+
"l",
31+
"r",
32+
"j",
33+
]
34+
35+
class ImageInfo(dict[str, Any]):
36+
@property
37+
def width(self) -> int: ...
38+
@property
39+
def height(self) -> int: ...
40+
@property
41+
def rendered_width(self) -> int: ...
42+
@property
43+
def rendered_height(self) -> int: ...
44+
def scale_inside_box(self, x: float, y: float, w: float, h: float) -> tuple[float, float, float, float]: ...
45+
@staticmethod
46+
def x_by_align(x: Align | _AlignLiteral, w: float, pdf: FPDF, keep_aspect_ratio: Literal[False]) -> float: ...
47+
48+
class RasterImageInfo(ImageInfo):
49+
def size_in_document_units(self, w: float, h: float, scale=1) -> tuple[float, float]: ...
50+
51+
class VectorImageInfo(ImageInfo): ...
52+
53+
@dataclass
54+
class ImageCache:
55+
images: dict[str, dict[Incomplete, Incomplete]] = ...
56+
icc_profiles: dict[bytes, int] = ...
57+
image_filter: _ImageFilter = "AUTO"
58+
59+
def reset_usages(self) -> None: ...

stubs/fpdf2/fpdf/image_parsing.pyi

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from _typeshed import Incomplete
2+
from dataclasses import dataclass
23
from io import BytesIO
34
from logging import Logger
45
from types import TracebackType
@@ -7,15 +8,29 @@ from typing_extensions import Literal, TypeAlias
78

89
from PIL import Image
910

11+
from .image_datastructures import ImageCache, ImageInfo, VectorImageInfo
12+
from .svg import SVGObject
13+
1014
_ImageFilter: TypeAlias = Literal["AUTO", "FlateDecode", "DCTDecode", "JPXDecode"]
1115

1216
RESAMPLE: Image.Resampling
17+
18+
@dataclass
19+
class ImageSettings:
20+
compression_level: int = -1
21+
1322
LOGGER: Logger
1423
SUPPORTED_IMAGE_FILTERS: tuple[_ImageFilter, ...]
24+
SETTINGS: ImageSettings
25+
1526
TIFFBitRevTable: list[int]
1627

28+
def preload_image(
29+
image_cache: ImageCache, name: str | BytesIO | Image.Image, dims: tuple[float, float] | None = None
30+
) -> tuple[str, BytesIO | Image.Image | None, ImageInfo]: ...
1731
def load_image(filename): ...
1832
def is_iccp_valid(iccp, filename) -> bool: ...
33+
def get_svg_info(filename: str, img: BytesIO, image_cache: ImageCache) -> tuple[str, SVGObject, VectorImageInfo]: ...
1934

2035
# Returned dict could be typed as a TypedDict.
2136
def get_img_info(

0 commit comments

Comments
 (0)