[fpdf2] Annotate drawing methods (#14923)

This commit is contained in:
Semyon Moroz
2025-10-31 00:39:28 +04:00
committed by GitHub
parent 08e890b769
commit 6ca882483f
2 changed files with 146 additions and 82 deletions
+145 -81
View File
@@ -1,18 +1,36 @@
import decimal
from _typeshed import Incomplete
import sys
from _typeshed import Incomplete, SupportsWrite
from collections import OrderedDict
from collections.abc import Callable, Generator, Sequence
from collections.abc import Callable, Generator, Iterable, Sequence
from contextlib import contextmanager
from re import Pattern
from typing import Any, ClassVar, Literal, NamedTuple, TypeVar, overload
from typing import Any, ClassVar, Literal, NamedTuple, Protocol, TypeVar, overload, type_check_only
from typing_extensions import Self, TypeAlias
if sys.version_info >= (3, 10):
from types import EllipsisType
else:
# Rely on builtins.ellipsis
from builtins import ellipsis as EllipsisType
from .enums import PathPaintRule
from .syntax import Name, Raw
__pdoc__: dict[str, bool]
_T = TypeVar("_T")
_CallableT = TypeVar("_CallableT", bound=Callable[..., Any])
@type_check_only
class _SupportsSerialize(Protocol):
def serialize(self) -> str: ...
@type_check_only
class _SupportsEndPoint(Protocol):
@property
def end_point(self) -> Point: ...
def force_nodocument(item: _CallableT) -> _CallableT: ...
def force_document(item: _CallableT) -> _CallableT: ...
@@ -23,12 +41,24 @@ EOL_CHARS: frozenset[str]
DELIMITERS: frozenset[str]
STR_ESC: Pattern[str]
STR_ESC_MAP: dict[str, str]
_Primitive: TypeAlias = (
_SupportsSerialize
| Number
| str
| bytes
| bool
| Raw
| list[_Primitive]
| tuple[_Primitive, ...]
| dict[Name, _Primitive]
| None
)
class GraphicsStateDictRegistry(OrderedDict[Raw, Name]):
def register_style(self, style: GraphicsStyle) -> Name | None: ...
def number_to_str(number) -> str: ...
def render_pdf_primitive(primitive) -> Raw: ...
def number_to_str(number: Number) -> str: ...
def render_pdf_primitive(primitive: _Primitive) -> Raw: ...
class _DeviceRGBBase(NamedTuple):
r: Number
@@ -72,8 +102,8 @@ class DeviceCMYK(_DeviceCMYKBase):
def colors(self) -> tuple[Number, Number, Number, Number]: ...
def serialize(self) -> str: ...
def rgb8(r, g, b, a=None) -> DeviceRGB: ...
def gray8(g, a=None) -> DeviceGray: ...
def rgb8(r: Number, g: Number, b: Number, a: Number | None = None) -> DeviceRGB: ...
def gray8(g: Number, a: Number | None = None) -> DeviceGray: ...
@overload
def convert_to_device_color(r: DeviceCMYK) -> DeviceCMYK: ...
@overload
@@ -87,24 +117,24 @@ def convert_to_device_color(r: int, g: Literal[-1] = -1, b: Literal[-1] = -1) ->
@overload
def convert_to_device_color(r: Sequence[int] | int, g: int, b: int) -> DeviceGray | DeviceRGB: ...
def cmyk8(c, m, y, k, a=None) -> DeviceCMYK: ...
def color_from_hex_string(hexstr) -> DeviceRGB: ...
def color_from_rgb_string(rgbstr) -> DeviceRGB: ...
def color_from_hex_string(hexstr: str) -> DeviceRGB: ...
def color_from_rgb_string(rgbstr: str) -> DeviceRGB: ...
class Point(NamedTuple):
x: Number
y: Number
def render(self): ...
def dot(self, other): ...
def angle(self, other): ...
def mag(self): ...
def __add__(self, other): ...
def __sub__(self, other): ...
def __neg__(self): ...
def __mul__(self, other): ...
def __rmul__(self, other): ...
def __truediv__(self, other): ...
def __floordiv__(self, other): ...
def __matmul__(self, other): ...
def render(self) -> str: ...
def dot(self, other: Point) -> Number: ...
def angle(self, other: Point) -> float: ...
def mag(self) -> Number: ...
def __add__(self, other: Point) -> Point: ... # type: ignore[override]
def __sub__(self, other: Point) -> Point: ...
def __neg__(self) -> Point: ...
def __mul__(self, other: Number) -> Point: ... # type: ignore[override]
def __rmul__(self, other: Number) -> Point: ... # type: ignore[override]
def __truediv__(self, other: Number) -> Point: ...
def __floordiv__(self, other: Number) -> Point: ...
def __matmul__(self, other: Transform) -> Point: ...
class Transform(NamedTuple):
a: Number
@@ -114,35 +144,35 @@ class Transform(NamedTuple):
e: Number
f: Number
@classmethod
def identity(cls): ...
def identity(cls) -> Self: ...
@classmethod
def translation(cls, x, y): ...
def translation(cls, x: Number, y: Number) -> Self: ...
@classmethod
def scaling(cls, x, y=None): ...
def scaling(cls, x: Number, y: Number | None = None) -> Self: ...
@classmethod
def rotation(cls, theta): ...
def rotation(cls, theta: Number) -> Self: ...
@classmethod
def rotation_d(cls, theta_d): ...
def rotation_d(cls, theta_d: Number) -> Self: ...
@classmethod
def shearing(cls, x, y=None): ...
def translate(self, x, y): ...
def scale(self, x, y=None): ...
def rotate(self, theta): ...
def rotate_d(self, theta_d): ...
def shear(self, x, y=None): ...
def about(self, x, y): ...
def __mul__(self, other): ...
def __rmul__(self, other): ...
def __matmul__(self, other): ...
def render(self, last_item): ...
def shearing(cls, x: Number, y: Number | None = None) -> Self: ...
def translate(self, x: Number, y: Number) -> Self: ...
def scale(self, x: Number, y: Number | None = None) -> Self: ...
def rotate(self, theta: Number) -> Self: ...
def rotate_d(self, theta_d: Number) -> Self: ...
def shear(self, x: Number, y: Number | None = None) -> Self: ...
def about(self, x: Number, y: Number) -> Transform: ...
def __mul__(self, other: Number) -> Transform: ... # type: ignore[override]
def __rmul__(self, other: Number) -> Transform: ... # type: ignore[override]
def __matmul__(self, other: Transform) -> Self: ...
def render(self, last_item: _T) -> tuple[str, _T]: ...
class GraphicsStyle:
INHERIT: ClassVar[Incomplete]
INHERIT: ClassVar[EllipsisType]
MERGE_PROPERTIES: ClassVar[tuple[str, ...]]
TRANSPARENCY_KEYS: ClassVar[tuple[Name, ...]]
PDF_STYLE_KEYS: ClassVar[tuple[Name, ...]]
@classmethod
def merge(cls, parent, child): ...
def merge(cls, parent, child) -> Self: ...
def __init__(self) -> None: ...
def __deepcopy__(self, memo) -> Self: ...
@property
@@ -150,13 +180,13 @@ class GraphicsStyle:
@allow_transparency.setter
def allow_transparency(self, new): ...
@property
def paint_rule(self): ...
def paint_rule(self) -> PathPaintRule | EllipsisType: ...
@paint_rule.setter
def paint_rule(self, new) -> None: ...
def paint_rule(self, new: PathPaintRule | str | EllipsisType | None) -> None: ...
@property
def auto_close(self): ...
def auto_close(self) -> bool | EllipsisType: ...
@auto_close.setter
def auto_close(self, new) -> None: ...
def auto_close(self, new: bool | EllipsisType) -> None: ...
@property
def intersection_rule(self): ...
@intersection_rule.setter
@@ -172,7 +202,7 @@ class GraphicsStyle:
@property
def stroke_color(self): ...
@stroke_color.setter
def stroke_color(self, color) -> None: ...
def stroke_color(self, color: str | DeviceRGB | DeviceGray | DeviceCMYK | EllipsisType | None) -> None: ...
@property
def stroke_opacity(self): ...
@stroke_opacity.setter
@@ -184,7 +214,7 @@ class GraphicsStyle:
@property
def stroke_width(self): ...
@stroke_width.setter
def stroke_width(self, width) -> None: ...
def stroke_width(self, width: Number | EllipsisType | None) -> None: ...
@property
def stroke_cap_style(self): ...
@stroke_cap_style.setter
@@ -196,36 +226,66 @@ class GraphicsStyle:
@property
def stroke_miter_limit(self): ...
@stroke_miter_limit.setter
def stroke_miter_limit(self, value) -> None: ...
def stroke_miter_limit(self, value: Number | EllipsisType) -> None: ...
@property
def stroke_dash_pattern(self): ...
@stroke_dash_pattern.setter
def stroke_dash_pattern(self, value) -> None: ...
def stroke_dash_pattern(self, value: Number | Iterable[Number] | EllipsisType | None) -> None: ...
@property
def stroke_dash_phase(self): ...
@stroke_dash_phase.setter
def stroke_dash_phase(self, value): ...
def stroke_dash_phase(self, value: Number | EllipsisType): ...
def serialize(self) -> Raw | None: ...
def resolve_paint_rule(self): ...
def resolve_paint_rule(self) -> PathPaintRule: ...
class Move(NamedTuple):
pt: Point
@property
def end_point(self): ...
def render(self, gsd_registry, style, last_item, initial_point): ...
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
def end_point(self) -> Point: ...
def render(
self, gsd_registry: GraphicsStateDictRegistry, style: GraphicsStyle, last_item: _SupportsEndPoint, initial_point: Point
) -> tuple[str, Self, Point]: ...
def render_debug(
self,
gsd_registry: GraphicsStateDictRegistry,
style: GraphicsStyle,
last_item: _SupportsEndPoint,
initial_point: Point,
debug_stream: SupportsWrite[str],
pfx: str,
) -> tuple[str, Self, Point]: ...
class RelativeMove(NamedTuple):
pt: Point
def render(self, gsd_registry, style, last_item, initial_point): ...
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
def render(
self, gsd_registry: GraphicsStateDictRegistry, style: GraphicsStyle, last_item: _SupportsEndPoint, initial_point: Point
) -> tuple[str, Move, Point]: ...
def render_debug(
self,
gsd_registry: GraphicsStateDictRegistry,
style: GraphicsStyle,
last_item: _SupportsEndPoint,
initial_point: Point,
debug_stream: SupportsWrite[str],
pfx: str,
) -> tuple[str, Move, Point]: ...
class Line(NamedTuple):
pt: Point
@property
def end_point(self): ...
def render(self, gsd_registry, style, last_item, initial_point): ...
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
def end_point(self) -> Point: ...
def render(
self, gsd_registry: GraphicsStateDictRegistry, style: GraphicsStyle, last_item: _SupportsEndPoint, initial_point: Point
) -> tuple[str, Self, Point]: ...
def render_debug(
self,
gsd_registry: GraphicsStateDictRegistry,
style: GraphicsStyle,
last_item: _SupportsEndPoint,
initial_point: Point,
debug_stream: SupportsWrite[str],
pfx: str,
) -> tuple[str, Self, Point]: ...
class RelativeLine(NamedTuple):
pt: Point
@@ -257,7 +317,7 @@ class BezierCurve(NamedTuple):
c2: Point
end: Point
@property
def end_point(self): ...
def end_point(self) -> Point: ...
def render(self, gsd_registry, style, last_item, initial_point): ...
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
@@ -272,7 +332,7 @@ class QuadraticBezierCurve(NamedTuple):
ctrl: Point
end: Point
@property
def end_point(self): ...
def end_point(self) -> Point: ...
def to_cubic_curve(self, start_point): ...
def render(self, gsd_registry, style, last_item, initial_point): ...
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
@@ -290,7 +350,7 @@ class Arc(NamedTuple):
sweep: bool
end: Point
@staticmethod
def subdivde_sweep(sweep_angle) -> Generator[Incomplete, None, None]: ...
def subdivde_sweep(sweep_angle: Number) -> Generator[tuple[Point, Point, Point]]: ...
def render(self, gsd_registry, style, last_item, initial_point): ...
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
@@ -337,10 +397,10 @@ class DrawingContext:
def render_debug(self, gsd_registry, first_point, scale, height, starting_style, debug_stream): ...
class PaintedPath:
def __init__(self, x: int = 0, y: int = 0) -> None: ...
def __init__(self, x: Number = 0, y: Number = 0) -> None: ...
def __deepcopy__(self, memo) -> Self: ...
@property
def style(self): ...
def style(self) -> GraphicsStyle: ...
@property
def transform(self): ...
@transform.setter
@@ -361,30 +421,34 @@ class PaintedPath:
def transform_group(self, transform) -> Generator[Self]: ...
def add_path_element(self, item, _copy: bool = True) -> None: ...
def remove_last_path_element(self) -> None: ...
def rectangle(self, x, y, w, h, rx: int = 0, ry: int = 0) -> Self: ...
def circle(self, cx, cy, r) -> Self: ...
def ellipse(self, cx, cy, rx, ry) -> Self: ...
def move_to(self, x, y) -> Self: ...
def move_relative(self, x, y) -> Self: ...
def line_to(self, x, y) -> Self: ...
def line_relative(self, dx, dy) -> Self: ...
def horizontal_line_to(self, x) -> Self: ...
def horizontal_line_relative(self, dx) -> Self: ...
def vertical_line_to(self, y) -> Self: ...
def vertical_line_relative(self, dy) -> Self: ...
def curve_to(self, x1, y1, x2, y2, x3, y3) -> Self: ...
def curve_relative(self, dx1, dy1, dx2, dy2, dx3, dy3) -> Self: ...
def quadratic_curve_to(self, x1, y1, x2, y2) -> Self: ...
def quadratic_curve_relative(self, dx1, dy1, dx2, dy2) -> Self: ...
def arc_to(self, rx, ry, rotation, large_arc, positive_sweep, x, y) -> Self: ...
def arc_relative(self, rx, ry, rotation, large_arc, positive_sweep, dx, dy) -> Self: ...
def rectangle(self, x: Number, y: Number, w: Number, h: Number, rx: Number = 0, ry: Number = 0) -> Self: ...
def circle(self, cx: Number, cy: Number, r: Number) -> Self: ...
def ellipse(self, cx: Number, cy: Number, rx: Number, ry: Number) -> Self: ...
def move_to(self, x: Number, y: Number) -> Self: ...
def move_relative(self, x: Number, y: Number) -> Self: ...
def line_to(self, x: Number, y: Number) -> Self: ...
def line_relative(self, dx: Number, dy: Number) -> Self: ...
def horizontal_line_to(self, x: Number) -> Self: ...
def horizontal_line_relative(self, dx: Number) -> Self: ...
def vertical_line_to(self, y: Number) -> Self: ...
def vertical_line_relative(self, dy: Number) -> Self: ...
def curve_to(self, x1: Number, y1: Number, x2: Number, y2: Number, x3: Number, y3: Number) -> Self: ...
def curve_relative(self, dx1: Number, dy1: Number, dx2: Number, dy2: Number, dx3: Number, dy3: Number) -> Self: ...
def quadratic_curve_to(self, x1: Number, y1: Number, x2: Number, y2: Number) -> Self: ...
def quadratic_curve_relative(self, dx1: Number, dy1: Number, dx2: Number, dy2: Number) -> Self: ...
def arc_to(
self, rx: Number, ry: Number, rotation: Number, large_arc: bool, positive_sweep: bool, x: Number, y: Number
) -> Self: ...
def arc_relative(
self, rx: Number, ry: Number, rotation: Number, large_arc: bool, positive_sweep: bool, dx: Number, dy: Number
) -> Self: ...
def close(self) -> None: ...
def render(self, gsd_registry, style, last_item, initial_point, debug_stream=None, pfx=None): ...
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
class ClippingPath(PaintedPath):
paint_rule: Incomplete
def __init__(self, x: int = 0, y: int = 0) -> None: ...
paint_rule: PathPaintRule
def __init__(self, x: Number = 0, y: Number = 0) -> None: ...
def render(self, gsd_registry, style, last_item, initial_point, debug_stream=None, pfx=None): ...
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
+1 -1
View File
@@ -14,7 +14,7 @@ class Extents(NamedTuple):
class TextRegionMixin:
def __init__(self, *args, **kwargs) -> None: ...
def register_text_region(self, region) -> None: ...
def is_current_text_region(self, region): ...
def is_current_text_region(self, region) -> bool: ...
def clear_text_region(self) -> None: ...
class LineWrapper(NamedTuple):