[fpdf2] add compatibility with fpdf2 2.7.6 (#10932)

This commit is contained in:
Matthias Schoettle
2023-11-15 09:11:59 -05:00
committed by GitHub
parent d1925f2bb6
commit dc4594a6e7
13 changed files with 341 additions and 78 deletions

View File

@@ -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"]

View File

@@ -17,6 +17,7 @@ __all__ = [
"FPDF",
"FPDFException",
"Align",
"TextMode",
"XPos",
"YPos",
"Template",

View File

@@ -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: ...

View File

@@ -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: ...

View File

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

View File

@@ -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]]

View File

@@ -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]: ...

View File

@@ -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: ...

View File

@@ -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): ...

View File

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

View File

@@ -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): ...

View File

@@ -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): ...

View File

@@ -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: ...