Update fpdf2 to 2.7.8 (#11410)

Closes: #11407
This commit is contained in:
Sebastian Rittau
2024-02-16 14:45:29 +01:00
committed by GitHub
parent cb27610970
commit 8a38ae62fb
10 changed files with 145 additions and 25 deletions

View File

@@ -5,6 +5,9 @@ fpdf.fpdf.FPDF.set_creation_date
# fonttools shims since we can't import it
fpdf._fonttools_shims
# Only present if harfbuzz is installed
fpdf.fonts.HarfBuzzFont
# Checking the following function crashes stubtest 0.991, but seems to be
# fixed in later versions.
fpdf.FPDF.set_encryption

View File

@@ -1,4 +1,4 @@
version = "2.7.7"
version = "2.7.8"
upstream_repository = "https://github.com/PyFPDF/fpdf2"
requires = ["types-Pillow>=9.2.0"]

62
stubs/fpdf2/fpdf/bidi.pyi Normal file
View File

@@ -0,0 +1,62 @@
from _typeshed import Incomplete
from collections.abc import Sequence
from dataclasses import dataclass
from typing import Final, Literal, TypedDict, type_check_only
MAX_DEPTH: Final = 125
@type_check_only
class _BracketInfo(TypedDict):
pair: str
type: Literal["o", "c"]
BIDI_BRACKETS: Final[dict[str, _BracketInfo]]
class BidiCharacter:
character_index: int
character: str
bidi_class: str
original_bidi_class: str
embedding_level: str
direction: Incomplete | None
def __init__(self, character_index: int, character: str, embedding_level: str, debug: bool) -> None: ...
def get_direction_from_level(self) -> Literal["L", "R"]: ...
def set_class(self, cls: str) -> None: ...
@dataclass
class DirectionalStatus:
embedding_level: int # between 0 and MAX_DEPTH
directional_override_status: Literal["N", "L", "R"]
directional_isolate_status: bool
class IsolatingRun:
characters: list[BidiCharacter]
previous_direction: str
next_direction: str
def __init__(self, characters: list[BidiCharacter], sos: str, eos: str) -> None: ...
def resolve_weak_types(self) -> None: ...
def pair_brackets(self) -> list[tuple[int, int]]: ...
def resolve_neutral_types(self) -> None: ...
def resolve_implicit_levels(self) -> None: ...
def auto_detect_base_direction(string: str, stop_at_pdi: bool = False, debug: bool = False) -> Literal["L", "R"]: ...
def calculate_isolate_runs(paragraph: Sequence[BidiCharacter]) -> list[IsolatingRun]: ...
class BidiParagraph:
text: str
base_direction: Literal["L", "R"]
debug: bool
base_embedding_level: int
characters: list[BidiCharacter]
def __init__(self, text: str, base_direction: Literal["L", "R"] | None = None, debug: bool = False) -> None: ...
def get_characters(self) -> list[BidiCharacter]: ...
def get_characters_with_embedding_level(self) -> list[BidiCharacter]: ...
def get_reordered_characters(self) -> list[BidiCharacter]: ...
def get_all(self) -> tuple[list[BidiCharacter], tuple[BidiCharacter, ...]]: ...
def get_reordered_string(self) -> str: ...
def get_bidi_fragments(self) -> tuple[tuple[str, Literal["L", "R"]], ...]: ...
def get_bidi_characters(self) -> None: ...
def split_bidi_fragments(self) -> tuple[tuple[str, Literal["L", "R"]], ...]: ...
def reorder_resolved_levels(self) -> tuple[BidiCharacter, ...]: ...

View File

@@ -73,6 +73,10 @@ class TableCellFillMode(CoerciveEnum):
def should_fill_cell(self, i: int, j: int) -> bool: ...
class TableSpan(CoerciveEnum):
ROW: Literal["ROW"]
COL: Literal["COL"]
class RenderStyle(CoerciveEnum):
D: str
F: str

View File

@@ -3,11 +3,16 @@ from _typeshed import Incomplete
from collections.abc import Generator
from dataclasses import dataclass
from typing import overload
from typing_extensions import Self
from .drawing import DeviceGray, DeviceRGB, Number
from .enums import TextEmphasis
from .syntax import PDFObject
# Only defined if harfbuzz is installed.
class HarfBuzzFont(Incomplete): # derives from uharfbuzz.Font
def __deepcopy__(self, _memo: object) -> Self: ...
@dataclass
class FontFace:
family: str | None
@@ -58,7 +63,7 @@ class TTFFont(_FontMixin):
glyph_ids: Incomplete
missing_glyphs: Incomplete
subset: Incomplete
hbfont: Incomplete
hbfont: HarfBuzzFont | None # Not always defined.
def __init__(self, fpdf, font_file_path, fontkey: str, style: int) -> None: ...
def close(self) -> None: ...
def get_text_width(self, text: str, font_size_pt: int, text_shaping_parms): ...

View File

@@ -156,8 +156,6 @@ class FPDF(GraphicsStateMixin):
w: float
h: float
text_shaping: dict[str, Incomplete] | None # TODO: TypedDict
def __init__(
self,
orientation: _Orientation = "portrait",
@@ -212,7 +210,7 @@ class FPDF(GraphicsStateMixin):
direction: Literal["ltr", "rtl"] | None = None,
script: str | None = None,
language: str | None = None,
): ...
) -> None: ...
def set_compression(self, compress: bool) -> None: ...
title: str
def set_title(self, title: str) -> None: ...

View File

@@ -1,9 +1,18 @@
from typing import Any, ClassVar
from fpdf.fonts import FontFace
from typing import Any, ClassVar, Literal, TypedDict, type_check_only
from .drawing import DeviceGray, DeviceRGB
from .enums import TextMode
from .fonts import FontFace
@type_check_only
class _TextShaping(TypedDict):
use_shaping_engine: bool
features: dict[str, bool]
direction: Literal["ltr", "rtl"]
script: str | None
language: str | None
fragment_direction: Literal["L", "R"] | None
paragraph_direction: Literal["L", "R"] | None
class GraphicsStateMixin:
DEFAULT_DRAW_COLOR: ClassVar[DeviceGray]
@@ -103,7 +112,7 @@ class GraphicsStateMixin:
@denom_lift.setter
def denom_lift(self, v) -> None: ...
@property
def text_shaping(self): ...
def text_shaping(self) -> _TextShaping | None: ...
@text_shaping.setter
def text_shaping(self, v) -> None: ...
def text_shaping(self, v: _TextShaping | None) -> None: ...
def font_face(self) -> FontFace: ...

View File

@@ -1,6 +1,6 @@
from _typeshed import Incomplete
from collections.abc import Callable, Sequence
from typing import Final, NamedTuple
from typing import Final, Literal, NamedTuple
from .enums import Align, WrapMode
@@ -54,18 +54,26 @@ class Fragment:
@property
def lift(self): ...
@property
def string(self): ...
def trim(self, index: int): ...
def string(self) -> str: ...
@property
def width(self) -> float: ...
@property
def text_shaping_parameters(self): ...
@property
def paragraph_direction(self) -> Literal["L", "R"]: ...
@property
def fragment_direction(self) -> Literal["L", "R"]: ...
def trim(self, index: int) -> None: ...
def __eq__(self, other: Fragment) -> bool: ... # type: ignore[override]
def get_width(self, start: int = 0, end: int | None = None, chars: str | None = None, initial_cs: bool = True): ...
def get_width(self, start: int = 0, end: int | None = None, chars: str | None = None, initial_cs: bool = True) -> float: ...
def get_character_width(self, character: str, print_sh: bool = False, initial_cs: bool = True): ...
def render_pdf_text(self, frag_ws, current_ws, word_spacing, adjust_x, adjust_y, h): ...
def render_pdf_text_ttf(self, frag_ws, word_spacing): ...
def render_with_text_shaping(self, pos_x, pos_y, h, word_spacing, text_shaping_parms): ...
def render_with_text_shaping(self, pos_x: float, pos_y: float, h: float, word_spacing: float) -> str: ...
def render_pdf_text_core(self, frag_ws, current_ws): ...
class TextLine(NamedTuple):
fragments: tuple[Incomplete, ...]
fragments: tuple[Fragment, ...]
text_width: float
number_of_spaces: int
align: Align
@@ -73,6 +81,7 @@ class TextLine(NamedTuple):
max_width: float
trailing_nl: bool = False
trailing_form_feed: bool = False
def get_ordered_fragments(self) -> tuple[Fragment, ...]: ...
class SpaceHint(NamedTuple):
original_fragment_index: int
@@ -97,13 +106,14 @@ class HyphenHint(NamedTuple):
class CurrentLine:
max_width: float
print_sh: Incomplete
fragments: Incomplete
width: int
fragments: list[Fragment]
height: int
number_of_spaces: int
space_break_hint: Incomplete
hyphen_break_hint: Incomplete
def __init__(self, max_width: float, print_sh: bool = False) -> None: ...
@property
def width(self) -> float: ...
def add_character(
self,
character: str,

View File

@@ -29,6 +29,7 @@ def resolve_length(length_str, default_unit: str = "pt"): ...
def resolve_angle(angle_str, default_unit: str = "deg"): ...
def xmlns(space, name): ...
def xmlns_lookup(space, *names): ...
def without_ns(qualified_tag: str) -> str: ...
shape_tags: Incomplete

View File

@@ -1,13 +1,13 @@
from _typeshed import Incomplete
from _typeshed import Incomplete, SupportsItems
from collections.abc import Iterable
from dataclasses import dataclass
from io import BytesIO
from typing import Literal
from typing import Literal, overload
from PIL import Image
from .drawing import DeviceGray, DeviceRGB
from .enums import Align, TableBordersLayout, TableCellFillMode, VAlign, WrapMode
from .enums import Align, TableBordersLayout, TableCellFillMode, TableSpan, VAlign, WrapMode
from .fonts import FontFace
from .fpdf import FPDF
from .util import Padding
@@ -43,7 +43,7 @@ class Table:
) -> None: ...
def row(self, cells: Iterable[str] = (), style: FontFace | None = None) -> Row: ...
def render(self) -> None: ...
def get_cell_border(self, i, j) -> str | Literal[0, 1]: ...
def get_cell_border(self, i: int, j: int, cell: Cell) -> str | Literal[0, 1]: ...
class Row:
cells: list[Cell]
@@ -52,7 +52,9 @@ class Row:
@property
def cols_count(self) -> int: ...
@property
def column_indices(self): ...
def max_rowspan(self) -> int: ...
def convert_spans(self, active_rowspans: SupportsItems[int, int]) -> tuple[dict[int, int], list[int]]: ...
@overload
def cell(
self,
text: str = "",
@@ -62,9 +64,24 @@ class Row:
img: str | Image.Image | BytesIO | None = None,
img_fill_width: bool = False,
colspan: int = 1,
rowspan: int = 1,
padding: tuple[float, ...] | None = None,
link: str | int | None = None,
) -> Cell: ...
) -> str: ...
@overload
def cell(
self,
text: TableSpan,
align: str | Align | None = None,
v_align: str | VAlign | None = None,
style: FontFace | None = None,
img: str | Image.Image | BytesIO | None = None,
img_fill_width: bool = False,
colspan: int = 1,
rowspan: int = 1,
padding: tuple[float, ...] | None = None,
link: str | int | None = None,
) -> TableSpan: ...
@dataclass
class Cell:
@@ -75,6 +92,7 @@ class Cell:
img: str | None
img_fill_width: bool
colspan: int
rowspan: int
padding: int | tuple[float, ...] | None
link: str | int | None
@@ -83,7 +101,17 @@ class Cell:
@dataclass(frozen=True)
class RowLayoutInfo:
height: int
triggers_page_jump: bool
pagebreak_height: float
rendered_height: dict[Incomplete, Incomplete]
merged_heights: list[Incomplete]
@dataclass(frozen=True)
class RowSpanLayoutInfo:
column: int
start: int
length: int
contents_height: float
def row_range(self) -> range: ...
def draw_box_borders(pdf: FPDF, x1, y1, x2, y2, border: str | Literal[0, 1], fill_color: Incomplete | None = None) -> None: ...