diff --git a/stubs/fpdf2/METADATA.toml b/stubs/fpdf2/METADATA.toml index f531f358f..8207ba527 100644 --- a/stubs/fpdf2/METADATA.toml +++ b/stubs/fpdf2/METADATA.toml @@ -1,4 +1,4 @@ -version = "2.7.6" +version = "2.7.7" 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 0ba2c5cfb..134f8df26 100644 --- a/stubs/fpdf2/fpdf/__init__.pyi +++ b/stubs/fpdf2/fpdf/__init__.pyi @@ -1,6 +1,7 @@ from pathlib import Path from .enums import Align as Align, TextMode as TextMode, XPos as XPos, YPos as YPos +from .fonts import FontFace as FontFace from .fpdf import FPDF as FPDF, FPDFException as FPDFException, TitleStyle as TitleStyle from .html import HTML2FPDF as HTML2FPDF, HTMLMixin as HTMLMixin from .prefs import ViewerPreferences as ViewerPreferences @@ -16,6 +17,7 @@ __all__ = [ "__license__", "FPDF", "FPDFException", + "FontFace", "Align", "TextMode", "XPos", diff --git a/stubs/fpdf2/fpdf/annotations.pyi b/stubs/fpdf2/fpdf/annotations.pyi index fc0b76521..c67abdf26 100644 --- a/stubs/fpdf2/fpdf/annotations.pyi +++ b/stubs/fpdf2/fpdf/annotations.pyi @@ -6,7 +6,7 @@ from .actions import Action from .enums import AnnotationFlag, AnnotationName, FileAttachmentAnnotationName from .syntax import Destination, Name, PDFContentStream, PDFObject -DEFAULT_ANNOT_FLAGS: Incomplete +DEFAULT_ANNOT_FLAGS: tuple[AnnotationFlag, ...] class AnnotationMixin: type: Name @@ -27,6 +27,7 @@ class AnnotationMixin: name: AnnotationName | FileAttachmentAnnotationName | None ink_list: str | None f_s: str | None + d_a: str | None def __init__( self, subtype: str, @@ -48,6 +49,7 @@ class AnnotationMixin: file_spec: str | None = None, field_type: str | None = None, value: Incomplete | None = None, + default_appearance: str | None = None, ) -> None: ... class PDFAnnotation(AnnotationMixin, PDFObject): ... diff --git a/stubs/fpdf2/fpdf/drawing.pyi b/stubs/fpdf2/fpdf/drawing.pyi index ed2aa272c..9cfa8a0f0 100644 --- a/stubs/fpdf2/fpdf/drawing.pyi +++ b/stubs/fpdf2/fpdf/drawing.pyi @@ -1,11 +1,11 @@ import decimal from _typeshed import Incomplete from collections import OrderedDict -from collections.abc import Callable, Generator, Iterator +from collections.abc import Callable, Generator, Iterator, Sequence from contextlib import contextmanager from re import Pattern -from typing import Any, ClassVar, NamedTuple, TypeVar -from typing_extensions import Self, TypeAlias +from typing import Any, ClassVar, NamedTuple, TypeVar, overload +from typing_extensions import Literal, Self, TypeAlias from .syntax import Name, Raw @@ -70,6 +70,14 @@ class DeviceCMYK(_DeviceCMYKBase): def rgb8(r, g, b, a: Incomplete | None = None) -> DeviceRGB: ... def gray8(g, a: Incomplete | None = None) -> DeviceGray: ... +@overload +def convert_to_device_color(r: DeviceGray, g: int = -1, b: int = -1) -> DeviceGray: ... +@overload +def convert_to_device_color(r: DeviceRGB, g: int = -1, b: int = -1) -> DeviceRGB: ... +@overload +def convert_to_device_color(r: int, g: Literal[-1] = -1, b: Literal[-1] = -1) -> DeviceGray: ... +@overload +def convert_to_device_color(r: Sequence[int] | int, g: int, b: int) -> DeviceGray | DeviceRGB: ... def cmyk8(c, m, y, k, a: Incomplete | None = None) -> DeviceCMYK: ... def color_from_hex_string(hexstr) -> DeviceRGB: ... def color_from_rgb_string(rgbstr) -> DeviceRGB: ... diff --git a/stubs/fpdf2/fpdf/enums.pyi b/stubs/fpdf2/fpdf/enums.pyi index a7001c393..a0a0ff8a7 100644 --- a/stubs/fpdf2/fpdf/enums.pyi +++ b/stubs/fpdf2/fpdf/enums.pyi @@ -70,6 +70,8 @@ class TableCellFillMode(CoerciveEnum): ROWS: str COLUMNS: str + def should_fill_cell(self, i: int, j: int) -> bool: ... + class RenderStyle(CoerciveEnum): D: str F: str diff --git a/stubs/fpdf2/fpdf/fonts.pyi b/stubs/fpdf2/fpdf/fonts.pyi index b99629adb..1c0a51155 100644 --- a/stubs/fpdf2/fpdf/fonts.pyi +++ b/stubs/fpdf2/fpdf/fonts.pyi @@ -2,6 +2,7 @@ import dataclasses from _typeshed import Incomplete from collections.abc import Generator from dataclasses import dataclass +from typing import overload from .drawing import DeviceGray, DeviceRGB, Number from .enums import TextEmphasis @@ -12,8 +13,8 @@ class FontFace: family: str | None emphasis: TextEmphasis | None size_pt: int | None - color: int | tuple[Number, Number, Number] | DeviceGray | DeviceRGB | None - fill_color: int | tuple[Number, Number, Number] | DeviceGray | DeviceRGB | None + color: DeviceGray | DeviceRGB | None + fill_color: DeviceGray | DeviceRGB | None def __init__( self, @@ -26,6 +27,13 @@ class FontFace: replace = dataclasses.replace + @overload + @staticmethod + def combine(default_style: None, override_style: None) -> None: ... # type: ignore[misc] + @overload + @staticmethod + def combine(default_style: FontFace | None, override_style: FontFace | None) -> FontFace: ... + class _FontMixin: i: int type: str diff --git a/stubs/fpdf2/fpdf/fpdf.pyi b/stubs/fpdf2/fpdf/fpdf.pyi index 079f64e94..0b67f20fc 100644 --- a/stubs/fpdf2/fpdf/fpdf.pyi +++ b/stubs/fpdf2/fpdf/fpdf.pyi @@ -6,7 +6,7 @@ from io import BytesIO from pathlib import PurePath from re import Pattern from typing import Any, ClassVar, NamedTuple, overload -from typing_extensions import Literal, TypeAlias +from typing_extensions import Final, Literal, TypeAlias, deprecated from fpdf import ViewerPreferences from PIL import Image @@ -35,6 +35,13 @@ from .errors import FPDFException as FPDFException from .fonts import FontFace from .graphics_state import GraphicsStateMixin from .html import HTML2FPDF +from .image_datastructures import ( + ImageCache, + ImageInfo as ImageInfo, + RasterImageInfo as RasterImageInfo, + VectorImageInfo as VectorImageInfo, + _AlignLiteral, +) from .output import OutputProducer, PDFPage from .recorder import FPDFRecorder from .structure_tree import StructureTreeBuilder @@ -42,23 +49,26 @@ from .syntax import DestinationXYZ from .table import Table from .util import _Unit -__all__ = ["FPDF", "XPos", "YPos", "get_page_format", "ImageInfo", "TextMode", "TitleStyle", "PAGE_FORMATS"] +__all__ = [ + "FPDF", + "XPos", + "YPos", + "get_page_format", + "ImageInfo", + "RasterImageInfo", + "VectorImageInfo", + "TextMode", + "TitleStyle", + "PAGE_FORMATS", +] _Orientation: TypeAlias = Literal["", "portrait", "p", "P", "landscape", "l", "L"] _Format: TypeAlias = Literal["", "a3", "A3", "a4", "A4", "a5", "A5", "letter", "Letter", "legal", "Legal"] _FontStyle: TypeAlias = Literal["", "B", "I"] _FontStyles: TypeAlias = Literal["", "B", "I", "U", "BU", "UB", "BI", "IB", "IU", "UI", "BIU", "BUI", "IBU", "IUB", "UBI", "UIB"] -PAGE_FORMATS: dict[_Format, tuple[float, float]] -class ImageInfo(dict[str, Any]): - @property - def width(self) -> int: ... - @property - def height(self) -> int: ... - @property - def rendered_width(self) -> int: ... - @property - def rendered_height(self) -> int: ... +FPDF_VERSION: Final[str] +PAGE_FORMATS: dict[_Format, tuple[float, float]] class TitleStyle(FontFace): t_margin: int | None @@ -87,7 +97,6 @@ def get_page_format(format: _Format | tuple[float, float], k: float | None = Non # TODO: TypedDicts _Font: TypeAlias = dict[str, Any] -_Image: TypeAlias = dict[str, Any] class FPDF(GraphicsStateMixin): MARKDOWN_BOLD_MARKER: ClassVar[str] @@ -102,15 +111,14 @@ class FPDF(GraphicsStateMixin): page: int pages: dict[int, PDFPage] fonts: dict[str, _Font] - images: dict[str, _Image] links: dict[int, DestinationXYZ] embedded_files: list[PDFEmbeddedFile] + image_cache: ImageCache in_footer: bool str_alias_nb_pages: str xmp_metadata: str | None - image_filter: str page_duration: int page_transition: Incomplete | None allow_images_transparency: bool @@ -148,6 +156,8 @@ class FPDF(GraphicsStateMixin): w: float h: float + text_shaping: dict[str, Incomplete] | None # TODO: TypedDict + def __init__( self, orientation: _Orientation = "portrait", @@ -371,7 +381,16 @@ class FPDF(GraphicsStateMixin): h: float = 1, name: AnnotationName | str | None = None, flags: tuple[AnnotationFlag, ...] | tuple[str, ...] = ..., - ) -> None: ... + ) -> AnnotationDict: ... + def free_text_annotation( + self, + text: str, + x: float | None = None, + y: float | None = None, + w: float | None = None, + h: float | None = None, + flags: tuple[AnnotationFlag, ...] | tuple[str, ...] = ..., + ) -> AnnotationDict: ... def add_action(self, action, x: float, y: float, w: float, h: float) -> None: ... def highlight( self, @@ -466,10 +485,12 @@ class FPDF(GraphicsStateMixin): def text_columns( self, text: str | None = None, + img: str | None = None, + img_fill_width: bool = False, ncols: int = 1, gutter: float = 10, balance: bool = False, - text_align: Align | str = "LEFT", + text_align: Align | _AlignLiteral = "LEFT", line_height: float = 1, l_margin: float | None = None, r_margin: float | None = None, @@ -490,7 +511,8 @@ class FPDF(GraphicsStateMixin): alt_text: str | None = None, dims: tuple[float, float] | None = None, keep_aspect_ratio: bool = False, - ) -> _Image: ... + ) -> RasterImageInfo | VectorImageInfo: ... + @deprecated("Deprecated since 2.7.7; use fpdf.image_parsing.preload_image() instead") def preload_image( self, name: str | Image.Image | BytesIO, dims: tuple[float, float] | None = None ) -> tuple[str, Any, ImageInfo]: ... diff --git a/stubs/fpdf2/fpdf/graphics_state.pyi b/stubs/fpdf2/fpdf/graphics_state.pyi index 029b4f6bf..fec06f18e 100644 --- a/stubs/fpdf2/fpdf/graphics_state.pyi +++ b/stubs/fpdf2/fpdf/graphics_state.pyi @@ -102,4 +102,8 @@ class GraphicsStateMixin: def denom_lift(self): ... @denom_lift.setter def denom_lift(self, v) -> None: ... + @property + def text_shaping(self): ... + @text_shaping.setter + def text_shaping(self, v) -> None: ... def font_face(self) -> FontFace: ... diff --git a/stubs/fpdf2/fpdf/image_datastructures.pyi b/stubs/fpdf2/fpdf/image_datastructures.pyi new file mode 100644 index 000000000..42ea9e5e5 --- /dev/null +++ b/stubs/fpdf2/fpdf/image_datastructures.pyi @@ -0,0 +1,59 @@ +from _typeshed import Incomplete +from dataclasses import dataclass +from typing import Any +from typing_extensions import Literal, TypeAlias + +from fpdf.enums import Align +from fpdf.fpdf import FPDF + +from .image_parsing import _ImageFilter + +_AlignLiteral: TypeAlias = Literal[ + "", + "CENTER", + "X_CENTER", + "LEFT", + "RIGHT", + "JUSTIFY", + "center", + "x_center", + "left", + "right", + "justify", + "C", + "X", + "L", + "R", + "J", + "c", + "x", + "l", + "r", + "j", +] + +class ImageInfo(dict[str, Any]): + @property + def width(self) -> int: ... + @property + def height(self) -> int: ... + @property + def rendered_width(self) -> int: ... + @property + def rendered_height(self) -> int: ... + def scale_inside_box(self, x: float, y: float, w: float, h: float) -> tuple[float, float, float, float]: ... + @staticmethod + def x_by_align(x: Align | _AlignLiteral, w: float, pdf: FPDF, keep_aspect_ratio: Literal[False]) -> float: ... + +class RasterImageInfo(ImageInfo): + def size_in_document_units(self, w: float, h: float, scale=1) -> tuple[float, float]: ... + +class VectorImageInfo(ImageInfo): ... + +@dataclass +class ImageCache: + images: dict[str, dict[Incomplete, Incomplete]] = ... + icc_profiles: dict[bytes, int] = ... + image_filter: _ImageFilter = "AUTO" + + def reset_usages(self) -> None: ... diff --git a/stubs/fpdf2/fpdf/image_parsing.pyi b/stubs/fpdf2/fpdf/image_parsing.pyi index acf3b6758..8c859cf0b 100644 --- a/stubs/fpdf2/fpdf/image_parsing.pyi +++ b/stubs/fpdf2/fpdf/image_parsing.pyi @@ -1,4 +1,5 @@ from _typeshed import Incomplete +from dataclasses import dataclass from io import BytesIO from logging import Logger from types import TracebackType @@ -7,15 +8,29 @@ from typing_extensions import Literal, TypeAlias from PIL import Image +from .image_datastructures import ImageCache, ImageInfo, VectorImageInfo +from .svg import SVGObject + _ImageFilter: TypeAlias = Literal["AUTO", "FlateDecode", "DCTDecode", "JPXDecode"] RESAMPLE: Image.Resampling + +@dataclass +class ImageSettings: + compression_level: int = -1 + LOGGER: Logger SUPPORTED_IMAGE_FILTERS: tuple[_ImageFilter, ...] +SETTINGS: ImageSettings + TIFFBitRevTable: list[int] +def preload_image( + image_cache: ImageCache, name: str | BytesIO | Image.Image, dims: tuple[float, float] | None = None +) -> tuple[str, BytesIO | Image.Image | None, ImageInfo]: ... def load_image(filename): ... def is_iccp_valid(iccp, filename) -> bool: ... +def get_svg_info(filename: str, img: BytesIO, image_cache: ImageCache) -> tuple[str, SVGObject, VectorImageInfo]: ... # Returned dict could be typed as a TypedDict. def get_img_info( diff --git a/stubs/fpdf2/fpdf/line_break.pyi b/stubs/fpdf2/fpdf/line_break.pyi index 1840ba1a2..302b2e156 100644 --- a/stubs/fpdf2/fpdf/line_break.pyi +++ b/stubs/fpdf2/fpdf/line_break.pyi @@ -1,14 +1,16 @@ from _typeshed import Incomplete from collections.abc import Callable, Sequence from typing import NamedTuple +from typing_extensions import Final from .enums import Align, WrapMode -SOFT_HYPHEN: str -HYPHEN: str -SPACE: str -NBSP: str -NEWLINE: str +SOFT_HYPHEN: Final[str] +HYPHEN: Final[str] +SPACE: Final[str] +NBSP: Final[str] +NEWLINE: Final[str] +FORM_FEED: Final[str] class Fragment: characters: list[str] @@ -70,7 +72,8 @@ class TextLine(NamedTuple): align: Align height: float max_width: float - trailing_nl: bool = ... + trailing_nl: bool = False + trailing_form_feed: bool = False class SpaceHint(NamedTuple): original_fragment_index: int @@ -114,8 +117,8 @@ class CurrentLine: url: str | None = None, ): ... def trim_trailing_spaces(self) -> None: ... - def manual_break(self, align: Align, trailing_nl: bool = False): ... - def automatic_break_possible(self): ... + def manual_break(self, align: Align, trailing_nl: bool = False, trailing_form_feed: bool = False) -> TextLine: ... + def automatic_break_possible(self) -> bool: ... def automatic_break(self, align: Align): ... class MultiLineBreak: diff --git a/stubs/fpdf2/fpdf/output.pyi b/stubs/fpdf2/fpdf/output.pyi index 03b078a7f..575d4d5d8 100644 --- a/stubs/fpdf2/fpdf/output.pyi +++ b/stubs/fpdf2/fpdf/output.pyi @@ -5,6 +5,8 @@ from typing_extensions import Final from .annotations import AnnotationDict from .encryption import StandardSecurityHandler +from .fpdf import FPDF +from .image_datastructures import RasterImageInfo from .syntax import Name, PDFArray, PDFContentStream, PDFObject, PDFString LOGGER: Logger @@ -172,12 +174,23 @@ class PDFXrefAndTrailer(ContentWithoutID): def serialize(self, _security_handler: StandardSecurityHandler | None = None) -> str: ... class OutputProducer: - fpdf: Incomplete + fpdf: FPDF pdf_objs: list[Incomplete] obj_id: int offsets: dict[Incomplete, Incomplete] trace_labels_per_obj_id: dict[Incomplete, Incomplete] sections_size_per_trace_label: defaultdict[Incomplete, int] buffer: bytearray - def __init__(self, fpdf) -> None: ... + def __init__(self, fpdf: FPDF) -> None: ... def bufferize(self) -> bytearray: ... + +def stream_content_for_raster_image( + info: RasterImageInfo, + x: float, + y: float, + w: float, + h: float, + keep_aspect_ratio: bool = False, + scale: float = 1, + pdf_height_to_flip: float | None = None, +) -> str: ... diff --git a/stubs/fpdf2/fpdf/svg.pyi b/stubs/fpdf2/fpdf/svg.pyi index 82f18d4a9..815c38a41 100644 --- a/stubs/fpdf2/fpdf/svg.pyi +++ b/stubs/fpdf2/fpdf/svg.pyi @@ -1,10 +1,16 @@ -from _typeshed import Incomplete +from _typeshed import Incomplete, Unused from collections.abc import Callable +from logging import Logger from re import Pattern - -from fpdf.drawing import PaintedPath +from typing import NamedTuple, overload +from typing_extensions import Literal from ._fonttools_shims import BasePen, _TTGlyphSet +from .drawing import ClippingPath, PaintedPath +from .fpdf import FPDF +from .image_datastructures import ImageCache + +LOGGER: Logger __pdoc__: dict[str, bool] @@ -40,20 +46,40 @@ def parse_style(svg_element) -> None: ... def apply_styles(stylable, svg_element) -> None: ... class ShapeBuilder: + @overload @staticmethod - def new_path(tag): ... + def new_path(tag, clipping_path: Literal[True]) -> ClippingPath: ... + @overload + @staticmethod + def new_path(tag, clipping_path: Literal[False] = False) -> PaintedPath: ... + @overload @classmethod - def rect(cls, tag): ... + def rect(cls, tag, clipping_path: Literal[True]) -> ClippingPath: ... + @overload @classmethod - def circle(cls, tag): ... + def rect(cls, tag, clipping_path: Literal[False] = False) -> PaintedPath: ... + @overload @classmethod - def ellipse(cls, tag): ... + def circle(cls, tag, clipping_path: Literal[True]) -> ClippingPath: ... + @overload @classmethod - def line(cls, tag): ... + def circle(cls, tag, clipping_path: Literal[False] = False) -> PaintedPath: ... + @overload @classmethod - def polyline(cls, tag): ... + def ellipse(cls, tag, clipping_path: Literal[True]) -> ClippingPath: ... + @overload @classmethod - def polygon(cls, tag): ... + def ellipse(cls, tag, clipping_path: Literal[False] = False) -> PaintedPath: ... + @classmethod + def line(cls, tag) -> PaintedPath: ... + @classmethod + def polyline(cls, tag) -> PaintedPath: ... + @overload + @classmethod + def polygon(cls, tag, clipping_path: Literal[True]) -> ClippingPath: ... + @overload + @classmethod + def polygon(cls, tag, clipping_path: Literal[False] = False) -> PaintedPath: ... def convert_transforms(tfstr): ... @@ -67,14 +93,17 @@ class PathPen(BasePen): def svg_path_converter(pdf_path: PaintedPath, svg_path: str) -> None: ... class SVGObject: + image_cache: ImageCache | None + @classmethod def from_file(cls, filename, *args, encoding: str = "utf-8", **kwargs): ... cross_references: Incomplete - def __init__(self, svg_text) -> None: ... + def __init__(self, svg_text, image_cache: ImageCache | None = None) -> None: ... preserve_ar: Incomplete width: Incomplete height: Incomplete viewbox: Incomplete + def update_xref(self, key: str | None, referenced) -> None: ... def extract_shape_info(self, root_tag) -> None: ... base_group: Incomplete def convert_graphics(self, root_tag) -> None: ... @@ -83,9 +112,29 @@ class SVGObject: self, scale, width, height, align_viewbox: bool = True, ignore_svg_top_attrs: bool = False ): ... def draw_to_page( - self, pdf, x: Incomplete | None = None, y: Incomplete | None = None, debug_stream: Incomplete | None = None + self, pdf: FPDF, x: Incomplete | None = None, y: Incomplete | None = None, debug_stream: Incomplete | None = None ) -> None: ... def handle_defs(self, defs) -> None: ... def build_xref(self, xref): ... def build_group(self, group, pdf_group: Incomplete | None = None): ... def build_path(self, path): ... + def build_shape(self, shape): ... + def build_clipping_path(self, shape, clip_id): ... + def apply_clipping_path(self, stylable, svg_element) -> None: ... + def build_image(self, image) -> SVGImage: ... + +class SVGImage(NamedTuple): + href: str + x: float + y: float + width: float + height: float + svg_obj: SVGObject + + def __deepcopy__(self, _memo: Unused) -> SVGImage: ... + def render( + self, _gsd_registry: Unused, _style: Unused, last_item, initial_point + ) -> tuple[Incomplete, Incomplete, Incomplete]: ... + def render_debug( + self, gsd_registry: Unused, style: Unused, last_item, initial_point, debug_stream, _pfx: Unused + ) -> tuple[Incomplete, Incomplete, Incomplete]: ... diff --git a/stubs/fpdf2/fpdf/table.pyi b/stubs/fpdf2/fpdf/table.pyi index 17579ca73..9dedab1be 100644 --- a/stubs/fpdf2/fpdf/table.pyi +++ b/stubs/fpdf2/fpdf/table.pyi @@ -14,13 +14,6 @@ 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] @@ -48,14 +41,14 @@ class Table: outer_border_width: float | None = None, num_heading_rows: int = 1, ) -> None: ... - def row(self, cells: Iterable[str] = ()) -> Row: ... + 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]: ... class Row: cells: list[Cell] style: FontFace - def __init__(self, fpdf: FPDF) -> None: ... + def __init__(self, table: Table, style: FontFace | None = None) -> None: ... @property def cols_count(self) -> int: ... @property @@ -86,3 +79,11 @@ class Cell: link: str | int | None def write(self, text, align: Incomplete | None = None): ... + +@dataclass(frozen=True) +class RowLayoutInfo: + height: int + triggers_page_jump: bool + rendered_height: dict[Incomplete, Incomplete] + +def draw_box_borders(pdf: FPDF, x1, y1, x2, y2, border: str | Literal[0, 1], fill_color: Incomplete | None = None) -> None: ... diff --git a/stubs/fpdf2/fpdf/text_region.pyi b/stubs/fpdf2/fpdf/text_region.pyi index 46aa47da8..bbdf463b3 100644 --- a/stubs/fpdf2/fpdf/text_region.pyi +++ b/stubs/fpdf2/fpdf/text_region.pyi @@ -1,8 +1,10 @@ from _typeshed import Incomplete from collections.abc import Sequence from typing import NamedTuple +from typing_extensions import Self from .enums import Align, WrapMode +from .image_datastructures import RasterImageInfo, VectorImageInfo, _AlignLiteral class Extents(NamedTuple): left: float @@ -45,9 +47,43 @@ class Paragraph: def ln(self, h: float | None = None) -> None: ... def build_lines(self, print_sh: bool) -> list[LineWrapper]: ... +class ImageParagraph: + region: Incomplete + name: Incomplete + align: Align | None + width: float | None + height: float | None + fill_width: bool + keep_aspect_ratio: bool + top_margin: float + bottom_margin: float + link: Incomplete | None + title: Incomplete | None + alt_text: Incomplete | None + img: Incomplete | None + info: Incomplete | None + + def __init__( + self, + region, + name, + align: Align | _AlignLiteral | None = None, + width: float | None = None, + height: float | None = None, + fill_width: bool = False, + keep_aspect_ratio: bool = False, + top_margin: float = 0, + bottom_margin: float = 0, + link: Incomplete | None = None, + title: Incomplete | None = None, + alt_text: Incomplete | None = None, + ) -> None: ... + def build_line(self) -> Self: ... + def render(self, col_left: float, col_width: float, max_height: float) -> VectorImageInfo | RasterImageInfo: ... + class ParagraphCollectorMixin: pdf: Incomplete - text_align: Align | str = "LEFT" + text_align: Align line_height: Incomplete print_sh: Incomplete wrapmode: Incomplete @@ -57,11 +93,13 @@ class ParagraphCollectorMixin: pdf, *args, text: str | None = None, - text_align: str = "LEFT", + text_align: Align | _AlignLiteral = "LEFT", line_height: float = 1.0, print_sh: bool = False, skip_leading_spaces: bool = False, wrapmode: WrapMode | None = None, + img: Incomplete | None = None, + img_fill_width: bool = False, **kwargs, ) -> None: ... def __enter__(self): ... @@ -78,6 +116,20 @@ class ParagraphCollectorMixin: wrapmode: WrapMode | None = None, ): ... def end_paragraph(self) -> None: ... + def image( + self, + name, + align: Align | _AlignLiteral | None = None, + width: float | None = None, + height: float | None = None, + fill_width: bool = False, + keep_aspect_ratio: bool = False, + top_margin: float = 0, + bottom_margin: float = 0, + link: Incomplete | None = None, + title: Incomplete | None = None, + alt_text: Incomplete | None = None, + ) -> None: ... class TextRegion(ParagraphCollectorMixin): def current_x_extents(self, y, height) -> None: ... @@ -93,6 +145,7 @@ class TextColumnarMixin: 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 __enter__(self) -> Self: ... + def new_column(self) -> None: ... def render(self) -> None: ... def current_x_extents(self, y, height): ...