diff --git a/stubs/fpdf2/METADATA.toml b/stubs/fpdf2/METADATA.toml index a47fe4aef..f531f358f 100644 --- a/stubs/fpdf2/METADATA.toml +++ b/stubs/fpdf2/METADATA.toml @@ -1,4 +1,4 @@ -version = "2.7.4" +version = "2.7.6" upstream_repository = "https://github.com/PyFPDF/fpdf2" requires = ["types-Pillow>=9.2.0"] diff --git a/stubs/fpdf2/fpdf/__init__.pyi b/stubs/fpdf2/fpdf/__init__.pyi index 9d17a7f7e..0ba2c5cfb 100644 --- a/stubs/fpdf2/fpdf/__init__.pyi +++ b/stubs/fpdf2/fpdf/__init__.pyi @@ -17,6 +17,7 @@ __all__ = [ "FPDF", "FPDFException", "Align", + "TextMode", "XPos", "YPos", "Template", diff --git a/stubs/fpdf2/fpdf/deprecation.pyi b/stubs/fpdf2/fpdf/deprecation.pyi index 89ab11760..a1399a561 100644 --- a/stubs/fpdf2/fpdf/deprecation.pyi +++ b/stubs/fpdf2/fpdf/deprecation.pyi @@ -1,7 +1,11 @@ from types import ModuleType from typing import Any, NoReturn +def support_deprecated_txt_arg(fn): ... + class WarnOnDeprecatedModuleAttributes(ModuleType): def __call__(self) -> NoReturn: ... def __getattr__(self, name: str) -> Any: ... def __setattr__(self, name: str, value: Any) -> None: ... + +def get_stack_level() -> int: ... diff --git a/stubs/fpdf2/fpdf/encryption.pyi b/stubs/fpdf2/fpdf/encryption.pyi index 45349dae5..38bf0a339 100644 --- a/stubs/fpdf2/fpdf/encryption.pyi +++ b/stubs/fpdf2/fpdf/encryption.pyi @@ -1,10 +1,10 @@ from _typeshed import Incomplete, SupportsLenAndGetItem from collections.abc import Generator, Iterable from logging import Logger -from typing import ClassVar, Protocol, TypeVar +from typing import ClassVar, Protocol, TypeVar, overload from typing_extensions import TypeAlias -from .enums import EncryptionMethod +from .enums import AccessPermission, EncryptionMethod from .fpdf import FPDF from .syntax import Name, PDFObject @@ -28,7 +28,7 @@ class CryptFilter: type: Name c_f_m: Name length: int - def __init__(self, mode, length) -> None: ... + def __init__(self, mode: str, length: int) -> None: ... def serialize(self) -> str: ... class EncryptionDictionary(PDFObject): @@ -54,8 +54,8 @@ class StandardSecurityHandler: encryption_method: EncryptionMethod | None cf: CryptFilter | None key_length: int - v: int - r: int + version: int + revision: int encrypt_metadata: bool # The following fields are only defined after a call to generate_passwords(). @@ -64,29 +64,46 @@ class StandardSecurityHandler: o: str k: str u: str + # The following field is only defined after a call to generate_user_password_rev6(). + ue: Incomplete + # The following field is only defined after a call to generate_owner_password_rev6(). + oe: Incomplete + # The following field is only defined after a call to generate_perms_rev6(). + perms_rev6: Incomplete def __init__( self, fpdf: FPDF, owner_password: str, user_password: str | None = None, - permission: Incomplete | None = None, - encryption_method: EncryptionMethod | None = None, + permission: AccessPermission = ..., + encryption_method: EncryptionMethod = ..., encrypt_metadata: bool = False, ) -> None: ... - def generate_passwords(self, file_id) -> None: ... + def generate_passwords(self, file_id: str) -> None: ... def get_encryption_obj(self) -> EncryptionDictionary: ... - def encrypt(self, text: str | bytes | bytearray, obj_id) -> bytes: ... - def encrypt_string(self, string, obj_id): ... - def encrypt_stream(self, stream, obj_id): ... + @overload + def encrypt(self, text: bytes | bytearray, obj_id: int) -> bytes: ... + @overload + def encrypt(self, text: str, obj_id: int) -> str: ... + def encrypt_string(self, string: str, obj_id: int) -> str: ... + def encrypt_stream(self, stream: bytes, obj_id: int) -> bytes: ... def is_aes_algorithm(self) -> bool: ... - def encrypt_bytes(self, data, obj_id) -> list[int]: ... - def encrypt_AES_cryptography(self, key, data): ... - def get_initialization_vector(self, size: int) -> bytearray: ... + def encrypt_bytes(self, data: bytes, obj_id: int) -> list[int]: ... + def encrypt_AES_cryptography(self, key: bytes, data: bytes) -> bytes: ... + @classmethod + def get_random_bytes(cls, size: int) -> bytes: ... + @classmethod + def prepare_string(cls, string: str) -> bytes: ... def padded_password(self, password: str) -> bytearray: ... def generate_owner_password(self) -> str: ... def generate_user_password(self) -> str: ... + @classmethod + def compute_hash(cls, input_password: bytes, salt: bytes, user_key: bytes = ...) -> bytes: ... + def generate_user_password_rev6(self) -> None: ... + def generate_owner_password_rev6(self) -> None: ... + def generate_perms_rev6(self) -> None: ... def generate_encryption_key(self) -> bytes: ... -def md5(data: bytes) -> bytes: ... +def md5(data: bytes | bytearray) -> bytes: ... def int32(n: int) -> int: ... diff --git a/stubs/fpdf2/fpdf/enums.pyi b/stubs/fpdf2/fpdf/enums.pyi index 112de3d17..a7001c393 100644 --- a/stubs/fpdf2/fpdf/enums.pyi +++ b/stubs/fpdf2/fpdf/enums.pyi @@ -37,6 +37,11 @@ class Align(CoerciveEnum): R: str J: str +class VAlign(CoerciveEnum): + M: str + T: str + B: str + class TextEmphasis(CoerciveIntFlag): B: int I: int @@ -103,6 +108,16 @@ class YPos(CoerciveEnum): TMARGIN: str BMARGIN: str +class Angle(CoerciveIntEnum): + NORTH: int + EAST: int + SOUTH: int + WEST: int + NORTHEAST: int + SOUTHEAST: int + SOUTHWEST: int + NORTHWEST: int + class PageLayout(CoerciveEnum): SINGLE_PAGE: Name ONE_COLUMN: Name @@ -236,3 +251,4 @@ class EncryptionMethod(Enum): NO_ENCRYPTION: int RC4: int AES_128: int + AES_256: int diff --git a/stubs/fpdf2/fpdf/fonts.pyi b/stubs/fpdf2/fpdf/fonts.pyi index b559d9f76..b99629adb 100644 --- a/stubs/fpdf2/fpdf/fonts.pyi +++ b/stubs/fpdf2/fpdf/fonts.pyi @@ -1,9 +1,11 @@ import dataclasses from _typeshed import Incomplete +from collections.abc import Generator from dataclasses import dataclass from .drawing import DeviceGray, DeviceRGB, Number from .enums import TextEmphasis +from .syntax import PDFObject @dataclass class FontFace: @@ -24,5 +26,81 @@ class FontFace: replace = dataclasses.replace +class _FontMixin: + i: int + type: str + name: str + up: int + ut: int + cw: int + fontkey: str + emphasis: TextEmphasis + def encode_text(self, text: str): ... + +class CoreFont(_FontMixin): + def __init__(self, fpdf, fontkey: str, style: int) -> None: ... + def get_text_width(self, text: str, font_size_pt: int, _): ... + +class TTFFont(_FontMixin): + ttffile: Incomplete + ttfont: Incomplete + scale: Incomplete + desc: Incomplete + cmap: Incomplete + glyph_ids: Incomplete + missing_glyphs: Incomplete + subset: Incomplete + hbfont: Incomplete + 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): ... + def shaped_text_width(self, text: str, font_size_pt: int, text_shaping_parms): ... + def perform_harfbuzz_shaping(self, text: str, font_size_pt: int, text_shaping_parms): ... + def shape_text(self, text: str, font_size_pt: int, text_shaping_parms): ... + +class PDFFontDescriptor(PDFObject): + type: Incomplete + ascent: Incomplete + descent: Incomplete + cap_height: Incomplete + flags: Incomplete + font_b_box: Incomplete + italic_angle: Incomplete + stem_v: Incomplete + missing_width: Incomplete + font_name: Incomplete + def __init__(self, ascent, descent, cap_height, flags, font_b_box, italic_angle, stem_v, missing_width) -> None: ... + +class Glyph: + glyph_id: int + unicode: tuple[Incomplete, ...] + glyph_name: str + glyph_width: int + def __hash__(self): ... + def __init__(self, glyph_id, unicode, glyph_name, glyph_width) -> None: ... + def __lt__(self, other): ... + def __gt__(self, other): ... + def __le__(self, other): ... + def __ge__(self, other): ... + + __match_args__ = ("glyph_id", "unicode", "glyph_name", "glyph_width") + +class SubsetMap: + font: TTFFont + def __init__(self, font: TTFFont, identities: list[int]) -> None: ... + def __len__(self) -> int: ... + def items(self) -> Generator[Incomplete, None, None]: ... + def pick(self, unicode: int): ... + def pick_glyph(self, glyph): ... + def get_glyph( + self, + glyph: Incomplete | None = None, + unicode: Incomplete | None = None, + glyph_name: Incomplete | None = None, + glyph_width: Incomplete | None = None, + ) -> Glyph: ... + def get_all_glyph_names(self): ... + +CORE_FONTS: dict[str, str] COURIER_FONT: dict[str, int] CORE_FONTS_CHARWIDTHS: dict[str, dict[str, int]] diff --git a/stubs/fpdf2/fpdf/fpdf.pyi b/stubs/fpdf2/fpdf/fpdf.pyi index d1607c6e1..e2b0a38bb 100644 --- a/stubs/fpdf2/fpdf/fpdf.pyi +++ b/stubs/fpdf2/fpdf/fpdf.pyi @@ -1,6 +1,6 @@ import datetime from _typeshed import Incomplete, StrPath, Unused -from collections.abc import Callable, Iterable, Sequence +from collections.abc import Callable, Generator, Iterable, Sequence from contextlib import _GeneratorContextManager from io import BytesIO from pathlib import PurePath @@ -83,12 +83,6 @@ class ToCPlaceholder(NamedTuple): y: int pages: int = ... -class SubsetMap: - def __init__(self, identities: Iterable[int]) -> None: ... - def __len__(self) -> int: ... - def pick(self, unicode: int) -> int: ... - def dict(self) -> dict[int, int]: ... - def get_page_format(format: _Format | tuple[float, float], k: float | None = None) -> tuple[float, float]: ... # TODO: TypedDicts @@ -101,6 +95,7 @@ class FPDF(GraphicsStateMixin): MARKDOWN_UNDERLINE_MARKER: ClassVar[str] MARKDOWN_LINK_REGEX: ClassVar[Pattern[str]] MARKDOWN_LINK_COLOR: ClassVar[Incomplete | None] + MARKDOWN_LINK_UNDERLINE: ClassVar[bool] HTML2FPDF_CLASS: ClassVar[type[HTML2FPDF]] @@ -200,6 +195,14 @@ class FPDF(GraphicsStateMixin): zoom: Literal["fullpage", "fullwidth", "real", "default"] | float, layout: Literal["single", "continuous", "two", "default"] = "continuous", ) -> None: ... + def set_text_shaping( + self, + use_shaping_engine: bool = True, + features: dict[str, bool] | None = None, + direction: Literal["ltr", "rtl"] | None = None, + script: str | None = None, + language: str | None = None, + ): ... def set_compression(self, compress: bool) -> None: ... title: str def set_title(self, title: str) -> None: ... @@ -397,12 +400,13 @@ class FPDF(GraphicsStateMixin): color: Sequence[float] = (1, 1, 0), border_width: int = 1, ) -> AnnotationDict: ... - def text(self, x: float, y: float, txt: str = "") -> None: ... + def text(self, x: float, y: float, text: str = "") -> None: ... def rotate(self, angle: float, x: float | None = None, y: float | None = None) -> None: ... def rotation(self, angle: float, x: float | None = None, y: float | None = None) -> _GeneratorContextManager[None]: ... def skew( self, ax: float = 0, ay: float = 0, x: float | None = None, y: float | None = None ) -> _GeneratorContextManager[None]: ... + def mirror(self, origin, angle) -> Generator[None, None, None]: ... def local_context( self, font_family: Incomplete | None = None, @@ -421,13 +425,13 @@ class FPDF(GraphicsStateMixin): self, w: float | None = None, h: float | None = None, - txt: str = "", + text: str = "", border: bool | Literal[0, 1] | str = 0, ln: int | Literal["DEPRECATED"] = "DEPRECATED", align: str | Align = ..., fill: bool = False, link: str = "", - center: bool | Literal["DEPRECATED"] = "DEPRECATED", + center: bool = False, markdown: bool = False, new_x: XPos | str = ..., new_y: YPos | str = ..., @@ -438,12 +442,12 @@ class FPDF(GraphicsStateMixin): self, w: float, h: float | None = None, - txt: str = "", + text: str = "", border: bool | Literal[0, 1] | str = 0, align: str | Align = ..., fill: bool = False, split_only: bool = False, - link: str | int = "", + link: str = "", ln: int | Literal["DEPRECATED"] = "DEPRECATED", max_line_height: float | None = None, markdown: bool = False, @@ -453,10 +457,26 @@ class FPDF(GraphicsStateMixin): wrapmode: WrapMode = ..., dry_run: bool = False, output: MethodReturnValue | str | int = ..., + center: bool = False, + padding: int = 0, ): ... def write( - self, h: float | None = None, txt: str = "", link: str = "", print_sh: bool = False, wrapmode: WrapMode = ... + self, h: float | None = None, text: str = "", link: str = "", print_sh: bool = False, wrapmode: WrapMode = ... ) -> bool: ... + def text_columns( + self, + text: str | None = None, + ncols: int = 1, + gutter: float = 10, + balance: bool = False, + text_align: Align | str = "LEFT", + line_height: float = 1, + l_margin: float | None = None, + r_margin: float | None = None, + print_sh: bool = False, + wrapmode: WrapMode = ..., + skip_leading_spaces: bool = False, + ): ... def image( self, name: str | Image.Image | BytesIO | StrPath, @@ -480,7 +500,7 @@ class FPDF(GraphicsStateMixin): def get_y(self) -> float: ... def set_y(self, y: float) -> None: ... def set_xy(self, x: float, y: float) -> None: ... - def normalize_text(self, txt: str) -> str: ... + def normalize_text(self, text: str) -> str: ... def sign_pkcs12( self, pkcs_filepath: str, @@ -505,8 +525,8 @@ class FPDF(GraphicsStateMixin): flags: tuple[AnnotationFlag, ...] = ..., ) -> None: ... def file_id(self) -> str: ... - def interleaved2of5(self, txt, x: float, y: float, w: float = 1, h: float = 10) -> None: ... - def code39(self, txt, x: float, y: float, w: float = 1.5, h: float = 5) -> None: ... + def interleaved2of5(self, text, x: float, y: float, w: float = 1, h: float = 10) -> None: ... + def code39(self, text, x: float, y: float, w: float = 1.5, h: float = 5) -> None: ... def rect_clip(self, x: float, y: float, w: float, h: float) -> _GeneratorContextManager[None]: ... def elliptic_clip(self, x: float, y: float, w: float, h: float) -> _GeneratorContextManager[None]: ... def round_clip(self, x: float, y: float, r: float) -> _GeneratorContextManager[None]: ... diff --git a/stubs/fpdf2/fpdf/html.pyi b/stubs/fpdf2/fpdf/html.pyi index 08516948d..25ea7f1da 100644 --- a/stubs/fpdf2/fpdf/html.pyi +++ b/stubs/fpdf2/fpdf/html.pyi @@ -2,7 +2,6 @@ from _typeshed import Incomplete, SupportsKeysAndGetItem, Unused from collections.abc import Callable, Iterable from html.parser import HTMLParser from logging import Logger -from re import Match, Pattern from typing import ClassVar from typing_extensions import Final @@ -14,31 +13,32 @@ __copyright__: Final[str] LOGGER: Logger BULLET_WIN1252: Final[str] DEFAULT_HEADING_SIZES: dict[str, int] -LEADING_SPACE: Pattern[str] -WHITESPACE: Pattern[str] -TRAILING_SPACE: Pattern[str] COLOR_DICT: Final[dict[str, str]] -def px2mm(px: float) -> float: ... def color_as_decimal(color: str | None = "#000000") -> tuple[int, int, int] | None: ... class HTML2FPDF(HTMLParser): HTML_UNCLOSED_TAGS: ClassVar[tuple[str, ...]] - pdf: Incomplete + pdf: FPDF image_map: Incomplete - li_tag_indent: Incomplete - table_line_separators: Incomplete - ul_bullet_char: Incomplete + li_tag_indent: int + dd_tag_indent: int + ul_bullet_char: str + heading_sizes: dict[str, int] + pre_code_font: str + warn_on_tags_not_matching: bool style: Incomplete + font_size: Incomplete + follows_trailing_space: bool + follows_heading: bool href: str align: str page_links: Incomplete font_stack: Incomplete indent: int bullet: Incomplete - font_size: Incomplete font_color: Incomplete table: Incomplete table_col_width: Incomplete @@ -54,11 +54,8 @@ class HTML2FPDF(HTMLParser): theader_out: bool table_row_height: int heading_level: Incomplete - heading_sizes: dict[str, int] heading_above: float heading_below: float - pre_code_font: str - warn_on_tags_not_matching: bool # Not initialized in __init__: font_face: Incomplete @@ -80,15 +77,12 @@ class HTML2FPDF(HTMLParser): def handle_data(self, data) -> None: ... def handle_starttag(self, tag, attrs) -> None: ... def handle_endtag(self, tag) -> None: ... - def set_font(self, face: Incomplete | None = None, size: Incomplete | None = None) -> None: ... + def set_font(self, face: Incomplete | None = None, size: Incomplete | None = None, set_default: bool = False) -> None: ... def set_style(self, tag: Incomplete | None = None, enable: bool = False) -> None: ... def set_text_color(self, r: Incomplete | None = None, g: int = 0, b: int = 0) -> None: ... - def put_link(self, txt) -> None: ... + def put_link(self, text) -> None: ... def render_toc(self, pdf, outline) -> None: ... def error(self, message: str) -> None: ... -def leading_whitespace_repl(matchobj: Match[str]) -> str: ... -def whitespace_repl(matchobj: Match[str]) -> str: ... - class HTMLMixin: def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... diff --git a/stubs/fpdf2/fpdf/line_break.pyi b/stubs/fpdf2/fpdf/line_break.pyi index 55a601e09..1840ba1a2 100644 --- a/stubs/fpdf2/fpdf/line_break.pyi +++ b/stubs/fpdf2/fpdf/line_break.pyi @@ -1,12 +1,13 @@ from _typeshed import Incomplete -from collections.abc import Sequence +from collections.abc import Callable, Sequence from typing import NamedTuple -from .enums import WrapMode +from .enums import Align, WrapMode SOFT_HYPHEN: str HYPHEN: str SPACE: str +NBSP: str NEWLINE: str class Fragment: @@ -15,7 +16,7 @@ class Fragment: k: float url: str | None def __init__( - self, characters: list[str] | str, graphics_state: dict[str, Incomplete], k: float, url: str | None = None + self, characters: list[str] | str, graphics_state: dict[str, Incomplete], k: float, link: str | int | None = None ) -> None: ... @property def font(self): ... @@ -57,12 +58,18 @@ class Fragment: 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_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_pdf_text_core(self, frag_ws, current_ws): ... class TextLine(NamedTuple): fragments: tuple[Incomplete, ...] text_width: float number_of_spaces: int - justify: bool + align: Align + height: float + max_width: float trailing_nl: bool = ... class SpaceHint(NamedTuple): @@ -86,13 +93,15 @@ class HyphenHint(NamedTuple): k: float class CurrentLine: + max_width: float print_sh: Incomplete fragments: Incomplete width: int + height: int number_of_spaces: int space_break_hint: Incomplete hyphen_break_hint: Incomplete - def __init__(self, print_sh: bool = False) -> None: ... + def __init__(self, max_width: float, print_sh: bool = False) -> None: ... def add_character( self, character: str, @@ -101,22 +110,35 @@ class CurrentLine: k: float, original_fragment_index: int, original_character_index: int, + height: float, url: str | None = None, ): ... def trim_trailing_spaces(self) -> None: ... - def manual_break(self, justify: bool = False, trailing_nl: bool = False): ... + def manual_break(self, align: Align, trailing_nl: bool = False): ... def automatic_break_possible(self): ... - def automatic_break(self, justify: bool): ... + def automatic_break(self, align: Align): ... class MultiLineBreak: - styled_text_fragments: Sequence[Fragment] - justify: bool + fragments: Sequence[Fragment] + get_width: float + margins: Sequence[float] + align: Align print_sh: bool - wrap_mode: WrapMode + wrapmode: WrapMode + line_height: float + skip_leading_spaces: bool fragment_index: int character_index: int idx_last_forced_break: int | None def __init__( - self, styled_text_fragments: Sequence[Fragment], justify: bool = False, print_sh: bool = False, wrapmode: WrapMode = ... + self, + fragments: Sequence[Fragment], + max_width: float | Callable[[float], float], + margins: Sequence[float], + align: Align = ..., + print_sh: bool = False, + wrapmode: WrapMode = ..., + line_height: float = 1.0, + skip_leading_spaces: bool = False, ) -> None: ... - def get_line_of_given_width(self, maximum_width: float, wordsplit: bool = True): ... + def get_line(self): ... diff --git a/stubs/fpdf2/fpdf/output.pyi b/stubs/fpdf2/fpdf/output.pyi index 1b01fb9fc..03b078a7f 100644 --- a/stubs/fpdf2/fpdf/output.pyi +++ b/stubs/fpdf2/fpdf/output.pyi @@ -39,19 +39,6 @@ class PDFFont(PDFObject): w: Incomplete | None = None, ) -> None: ... -class PDFFontDescriptor(PDFObject): - type: Name - ascent: Incomplete - descent: Incomplete - cap_height: Incomplete - flags: Incomplete - font_b_box: Incomplete - italic_angle: Incomplete - stem_v: Incomplete - missing_width: Incomplete - font_name: Incomplete | None - def __init__(self, ascent, descent, cap_height, flags, font_b_box, italic_angle, stem_v, missing_width) -> None: ... - class CIDSystemInfo(PDFObject): registry: PDFString ordering: PDFString diff --git a/stubs/fpdf2/fpdf/table.pyi b/stubs/fpdf2/fpdf/table.pyi index 4586a178d..17579ca73 100644 --- a/stubs/fpdf2/fpdf/table.pyi +++ b/stubs/fpdf2/fpdf/table.pyi @@ -7,16 +7,19 @@ from typing_extensions import Literal from PIL import Image from .drawing import DeviceGray, DeviceRGB -from .enums import Align, TableBordersLayout, TableCellFillMode +from .enums import Align, TableBordersLayout, TableCellFillMode, VAlign, WrapMode from .fonts import FontFace from .fpdf import FPDF +from .util import Padding DEFAULT_HEADINGS_STYLE: FontFace +def draw_box_borders(pdf: FPDF, x1, y1, x2, y2, border: str | Literal[0, 1], fill_color: Incomplete | None = None) -> None: ... @dataclass(frozen=True) class RowLayoutInfo: height: int triggers_page_jump: bool + rendered_height: dict[Incomplete, Incomplete] class Table: rows: list[Row] @@ -27,16 +30,23 @@ class Table: rows: Iterable[str] = (), *, align: str | Align = "CENTER", + v_align: str | VAlign = "MIDDLE", borders_layout: str | TableBordersLayout = ..., cell_fill_color: int | tuple[Incomplete, ...] | DeviceGray | DeviceRGB | None = None, cell_fill_mode: str | TableCellFillMode = ..., col_widths: int | tuple[int, ...] | None = None, first_row_as_headings: bool = True, + gutter_height: float = 0, + gutter_width: float = 0, headings_style: FontFace = ..., line_height: int | None = None, - markdown=False, + markdown: bool = False, text_align: str | Align = "JUSTIFY", width: int | None = None, + wrapmode: WrapMode = ..., + padding: float | Padding | None = None, + outer_border_width: float | None = None, + num_heading_rows: int = 1, ) -> None: ... def row(self, cells: Iterable[str] = ()) -> Row: ... def render(self) -> None: ... @@ -48,23 +58,31 @@ class Row: def __init__(self, fpdf: FPDF) -> None: ... @property def cols_count(self) -> int: ... + @property + def column_indices(self): ... def cell( self, text: str = "", 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, + padding: tuple[float, ...] | None = None, + link: str | int | None = None, ) -> Cell: ... @dataclass class Cell: text: str align: str | Align | None + v_align: str | VAlign | None style: FontFace | None img: str | None img_fill_width: bool colspan: int + padding: int | tuple[float, ...] | None + link: str | int | None def write(self, text, align: Incomplete | None = None): ... diff --git a/stubs/fpdf2/fpdf/text_region.pyi b/stubs/fpdf2/fpdf/text_region.pyi new file mode 100644 index 000000000..46aa47da8 --- /dev/null +++ b/stubs/fpdf2/fpdf/text_region.pyi @@ -0,0 +1,98 @@ +from _typeshed import Incomplete +from collections.abc import Sequence +from typing import NamedTuple + +from .enums import Align, WrapMode + +class Extents(NamedTuple): + left: float + right: float + +class TextRegionMixin: + def __init__(self, *args, **kwargs) -> None: ... + def register_text_region(self, region) -> None: ... + def is_current_text_region(self, region): ... + def clear_text_region(self) -> None: ... + +class LineWrapper(NamedTuple): + line: Sequence[Incomplete] + paragraph: Paragraph + first_line: bool = False + last_line: bool = False + +class Paragraph: + pdf: Incomplete + text_align: Incomplete + line_height: Incomplete + top_margin: Incomplete + bottom_margin: Incomplete + skip_leading_spaces: Incomplete + wrapmode: Incomplete + + def __init__( + self, + region, + text_align: Incomplete | None = None, + line_height: Incomplete | None = None, + top_margin: float = 0, + bottom_margin: float = 0, + skip_leading_spaces: bool = False, + wrapmode: WrapMode | None = None, + ) -> None: ... + def __enter__(self): ... + def __exit__(self, exc_type, exc_value, traceback) -> None: ... + def write(self, text: str, link: Incomplete | None = None): ... + def ln(self, h: float | None = None) -> None: ... + def build_lines(self, print_sh: bool) -> list[LineWrapper]: ... + +class ParagraphCollectorMixin: + pdf: Incomplete + text_align: Align | str = "LEFT" + line_height: Incomplete + print_sh: Incomplete + wrapmode: Incomplete + skip_leading_spaces: Incomplete + def __init__( + self, + pdf, + *args, + text: str | None = None, + text_align: str = "LEFT", + line_height: float = 1.0, + print_sh: bool = False, + skip_leading_spaces: bool = False, + wrapmode: WrapMode | None = None, + **kwargs, + ) -> None: ... + def __enter__(self): ... + def __exit__(self, exc_type, exc_value, traceback) -> None: ... + def write(self, text: str, link: Incomplete | None = None): ... + def ln(self, h: float | None = None) -> None: ... + def paragraph( + self, + text_align: Incomplete | None = None, + line_height: Incomplete | None = None, + skip_leading_spaces: bool = False, + top_margin: int = 0, + bottom_margin: int = 0, + wrapmode: WrapMode | None = None, + ): ... + def end_paragraph(self) -> None: ... + +class TextRegion(ParagraphCollectorMixin): + def current_x_extents(self, y, height) -> None: ... + def collect_lines(self): ... + def render(self) -> None: ... + def get_width(self, height): ... + +class TextColumnarMixin: + l_margin: Incomplete + r_margin: Incomplete + def __init__(self, pdf, *args, l_margin: Incomplete | None = None, r_margin: Incomplete | None = None, **kwargs) -> None: ... + +class TextColumns(TextRegion, TextColumnarMixin): + balance: Incomplete + def __init__(self, pdf, *args, ncols: int = 1, gutter: float = 10, balance: bool = False, **kwargs) -> None: ... + def __enter__(self): ... + def render(self) -> None: ... + def current_x_extents(self, y, height): ... diff --git a/stubs/fpdf2/fpdf/util.pyi b/stubs/fpdf2/fpdf/util.pyi index d078ec0ab..63b13b49e 100644 --- a/stubs/fpdf2/fpdf/util.pyi +++ b/stubs/fpdf2/fpdf/util.pyi @@ -1,11 +1,19 @@ from collections.abc import Iterable -from typing import Any, AnyStr +from typing import Any, AnyStr, NamedTuple from typing_extensions import Final, Literal, TypeAlias _Unit: TypeAlias = Literal["pt", "mm", "cm", "in"] PIL_MEM_BLOCK_SIZE_IN_MIB: Final = 16 +class Padding(NamedTuple): + top: float = 0 + right: float = 0 + bottom: float = 0 + left: float = 0 + @classmethod + def new(cls, padding: float | tuple[float, ...] | list[float]): ... + def buffer_subst(buffer: bytearray, placeholder: str, value: str) -> bytearray: ... def escape_parens(s: AnyStr) -> AnyStr: ... def get_scale_factor(unit: _Unit | float) -> float: ...