Skip to content

Commit 6ca8824

Browse files
authored
[fpdf2] Annotate drawing methods (#14923)
1 parent 08e890b commit 6ca8824

File tree

2 files changed

+146
-82
lines changed

2 files changed

+146
-82
lines changed

stubs/fpdf2/fpdf/drawing.pyi

Lines changed: 145 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,36 @@
11
import decimal
2-
from _typeshed import Incomplete
2+
import sys
3+
from _typeshed import Incomplete, SupportsWrite
34
from collections import OrderedDict
4-
from collections.abc import Callable, Generator, Sequence
5+
from collections.abc import Callable, Generator, Iterable, Sequence
56
from contextlib import contextmanager
67
from re import Pattern
7-
from typing import Any, ClassVar, Literal, NamedTuple, TypeVar, overload
8+
from typing import Any, ClassVar, Literal, NamedTuple, Protocol, TypeVar, overload, type_check_only
89
from typing_extensions import Self, TypeAlias
910

11+
if sys.version_info >= (3, 10):
12+
from types import EllipsisType
13+
else:
14+
# Rely on builtins.ellipsis
15+
from builtins import ellipsis as EllipsisType
16+
17+
from .enums import PathPaintRule
1018
from .syntax import Name, Raw
1119

1220
__pdoc__: dict[str, bool]
1321

22+
_T = TypeVar("_T")
1423
_CallableT = TypeVar("_CallableT", bound=Callable[..., Any])
1524

25+
@type_check_only
26+
class _SupportsSerialize(Protocol):
27+
def serialize(self) -> str: ...
28+
29+
@type_check_only
30+
class _SupportsEndPoint(Protocol):
31+
@property
32+
def end_point(self) -> Point: ...
33+
1634
def force_nodocument(item: _CallableT) -> _CallableT: ...
1735
def force_document(item: _CallableT) -> _CallableT: ...
1836

@@ -23,12 +41,24 @@ EOL_CHARS: frozenset[str]
2341
DELIMITERS: frozenset[str]
2442
STR_ESC: Pattern[str]
2543
STR_ESC_MAP: dict[str, str]
44+
_Primitive: TypeAlias = (
45+
_SupportsSerialize
46+
| Number
47+
| str
48+
| bytes
49+
| bool
50+
| Raw
51+
| list[_Primitive]
52+
| tuple[_Primitive, ...]
53+
| dict[Name, _Primitive]
54+
| None
55+
)
2656

2757
class GraphicsStateDictRegistry(OrderedDict[Raw, Name]):
2858
def register_style(self, style: GraphicsStyle) -> Name | None: ...
2959

30-
def number_to_str(number) -> str: ...
31-
def render_pdf_primitive(primitive) -> Raw: ...
60+
def number_to_str(number: Number) -> str: ...
61+
def render_pdf_primitive(primitive: _Primitive) -> Raw: ...
3262

3363
class _DeviceRGBBase(NamedTuple):
3464
r: Number
@@ -72,8 +102,8 @@ class DeviceCMYK(_DeviceCMYKBase):
72102
def colors(self) -> tuple[Number, Number, Number, Number]: ...
73103
def serialize(self) -> str: ...
74104

75-
def rgb8(r, g, b, a=None) -> DeviceRGB: ...
76-
def gray8(g, a=None) -> DeviceGray: ...
105+
def rgb8(r: Number, g: Number, b: Number, a: Number | None = None) -> DeviceRGB: ...
106+
def gray8(g: Number, a: Number | None = None) -> DeviceGray: ...
77107
@overload
78108
def convert_to_device_color(r: DeviceCMYK) -> DeviceCMYK: ...
79109
@overload
@@ -87,24 +117,24 @@ def convert_to_device_color(r: int, g: Literal[-1] = -1, b: Literal[-1] = -1) ->
87117
@overload
88118
def convert_to_device_color(r: Sequence[int] | int, g: int, b: int) -> DeviceGray | DeviceRGB: ...
89119
def cmyk8(c, m, y, k, a=None) -> DeviceCMYK: ...
90-
def color_from_hex_string(hexstr) -> DeviceRGB: ...
91-
def color_from_rgb_string(rgbstr) -> DeviceRGB: ...
120+
def color_from_hex_string(hexstr: str) -> DeviceRGB: ...
121+
def color_from_rgb_string(rgbstr: str) -> DeviceRGB: ...
92122

93123
class Point(NamedTuple):
94124
x: Number
95125
y: Number
96-
def render(self): ...
97-
def dot(self, other): ...
98-
def angle(self, other): ...
99-
def mag(self): ...
100-
def __add__(self, other): ...
101-
def __sub__(self, other): ...
102-
def __neg__(self): ...
103-
def __mul__(self, other): ...
104-
def __rmul__(self, other): ...
105-
def __truediv__(self, other): ...
106-
def __floordiv__(self, other): ...
107-
def __matmul__(self, other): ...
126+
def render(self) -> str: ...
127+
def dot(self, other: Point) -> Number: ...
128+
def angle(self, other: Point) -> float: ...
129+
def mag(self) -> Number: ...
130+
def __add__(self, other: Point) -> Point: ... # type: ignore[override]
131+
def __sub__(self, other: Point) -> Point: ...
132+
def __neg__(self) -> Point: ...
133+
def __mul__(self, other: Number) -> Point: ... # type: ignore[override]
134+
def __rmul__(self, other: Number) -> Point: ... # type: ignore[override]
135+
def __truediv__(self, other: Number) -> Point: ...
136+
def __floordiv__(self, other: Number) -> Point: ...
137+
def __matmul__(self, other: Transform) -> Point: ...
108138

109139
class Transform(NamedTuple):
110140
a: Number
@@ -114,49 +144,49 @@ class Transform(NamedTuple):
114144
e: Number
115145
f: Number
116146
@classmethod
117-
def identity(cls): ...
147+
def identity(cls) -> Self: ...
118148
@classmethod
119-
def translation(cls, x, y): ...
149+
def translation(cls, x: Number, y: Number) -> Self: ...
120150
@classmethod
121-
def scaling(cls, x, y=None): ...
151+
def scaling(cls, x: Number, y: Number | None = None) -> Self: ...
122152
@classmethod
123-
def rotation(cls, theta): ...
153+
def rotation(cls, theta: Number) -> Self: ...
124154
@classmethod
125-
def rotation_d(cls, theta_d): ...
155+
def rotation_d(cls, theta_d: Number) -> Self: ...
126156
@classmethod
127-
def shearing(cls, x, y=None): ...
128-
def translate(self, x, y): ...
129-
def scale(self, x, y=None): ...
130-
def rotate(self, theta): ...
131-
def rotate_d(self, theta_d): ...
132-
def shear(self, x, y=None): ...
133-
def about(self, x, y): ...
134-
def __mul__(self, other): ...
135-
def __rmul__(self, other): ...
136-
def __matmul__(self, other): ...
137-
def render(self, last_item): ...
157+
def shearing(cls, x: Number, y: Number | None = None) -> Self: ...
158+
def translate(self, x: Number, y: Number) -> Self: ...
159+
def scale(self, x: Number, y: Number | None = None) -> Self: ...
160+
def rotate(self, theta: Number) -> Self: ...
161+
def rotate_d(self, theta_d: Number) -> Self: ...
162+
def shear(self, x: Number, y: Number | None = None) -> Self: ...
163+
def about(self, x: Number, y: Number) -> Transform: ...
164+
def __mul__(self, other: Number) -> Transform: ... # type: ignore[override]
165+
def __rmul__(self, other: Number) -> Transform: ... # type: ignore[override]
166+
def __matmul__(self, other: Transform) -> Self: ...
167+
def render(self, last_item: _T) -> tuple[str, _T]: ...
138168

139169
class GraphicsStyle:
140-
INHERIT: ClassVar[Incomplete]
170+
INHERIT: ClassVar[EllipsisType]
141171
MERGE_PROPERTIES: ClassVar[tuple[str, ...]]
142172
TRANSPARENCY_KEYS: ClassVar[tuple[Name, ...]]
143173
PDF_STYLE_KEYS: ClassVar[tuple[Name, ...]]
144174
@classmethod
145-
def merge(cls, parent, child): ...
175+
def merge(cls, parent, child) -> Self: ...
146176
def __init__(self) -> None: ...
147177
def __deepcopy__(self, memo) -> Self: ...
148178
@property
149179
def allow_transparency(self): ...
150180
@allow_transparency.setter
151181
def allow_transparency(self, new): ...
152182
@property
153-
def paint_rule(self): ...
183+
def paint_rule(self) -> PathPaintRule | EllipsisType: ...
154184
@paint_rule.setter
155-
def paint_rule(self, new) -> None: ...
185+
def paint_rule(self, new: PathPaintRule | str | EllipsisType | None) -> None: ...
156186
@property
157-
def auto_close(self): ...
187+
def auto_close(self) -> bool | EllipsisType: ...
158188
@auto_close.setter
159-
def auto_close(self, new) -> None: ...
189+
def auto_close(self, new: bool | EllipsisType) -> None: ...
160190
@property
161191
def intersection_rule(self): ...
162192
@intersection_rule.setter
@@ -172,7 +202,7 @@ class GraphicsStyle:
172202
@property
173203
def stroke_color(self): ...
174204
@stroke_color.setter
175-
def stroke_color(self, color) -> None: ...
205+
def stroke_color(self, color: str | DeviceRGB | DeviceGray | DeviceCMYK | EllipsisType | None) -> None: ...
176206
@property
177207
def stroke_opacity(self): ...
178208
@stroke_opacity.setter
@@ -184,7 +214,7 @@ class GraphicsStyle:
184214
@property
185215
def stroke_width(self): ...
186216
@stroke_width.setter
187-
def stroke_width(self, width) -> None: ...
217+
def stroke_width(self, width: Number | EllipsisType | None) -> None: ...
188218
@property
189219
def stroke_cap_style(self): ...
190220
@stroke_cap_style.setter
@@ -196,36 +226,66 @@ class GraphicsStyle:
196226
@property
197227
def stroke_miter_limit(self): ...
198228
@stroke_miter_limit.setter
199-
def stroke_miter_limit(self, value) -> None: ...
229+
def stroke_miter_limit(self, value: Number | EllipsisType) -> None: ...
200230
@property
201231
def stroke_dash_pattern(self): ...
202232
@stroke_dash_pattern.setter
203-
def stroke_dash_pattern(self, value) -> None: ...
233+
def stroke_dash_pattern(self, value: Number | Iterable[Number] | EllipsisType | None) -> None: ...
204234
@property
205235
def stroke_dash_phase(self): ...
206236
@stroke_dash_phase.setter
207-
def stroke_dash_phase(self, value): ...
237+
def stroke_dash_phase(self, value: Number | EllipsisType): ...
208238
def serialize(self) -> Raw | None: ...
209-
def resolve_paint_rule(self): ...
239+
def resolve_paint_rule(self) -> PathPaintRule: ...
210240

211241
class Move(NamedTuple):
212242
pt: Point
213243
@property
214-
def end_point(self): ...
215-
def render(self, gsd_registry, style, last_item, initial_point): ...
216-
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
244+
def end_point(self) -> Point: ...
245+
def render(
246+
self, gsd_registry: GraphicsStateDictRegistry, style: GraphicsStyle, last_item: _SupportsEndPoint, initial_point: Point
247+
) -> tuple[str, Self, Point]: ...
248+
def render_debug(
249+
self,
250+
gsd_registry: GraphicsStateDictRegistry,
251+
style: GraphicsStyle,
252+
last_item: _SupportsEndPoint,
253+
initial_point: Point,
254+
debug_stream: SupportsWrite[str],
255+
pfx: str,
256+
) -> tuple[str, Self, Point]: ...
217257

218258
class RelativeMove(NamedTuple):
219259
pt: Point
220-
def render(self, gsd_registry, style, last_item, initial_point): ...
221-
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
260+
def render(
261+
self, gsd_registry: GraphicsStateDictRegistry, style: GraphicsStyle, last_item: _SupportsEndPoint, initial_point: Point
262+
) -> tuple[str, Move, Point]: ...
263+
def render_debug(
264+
self,
265+
gsd_registry: GraphicsStateDictRegistry,
266+
style: GraphicsStyle,
267+
last_item: _SupportsEndPoint,
268+
initial_point: Point,
269+
debug_stream: SupportsWrite[str],
270+
pfx: str,
271+
) -> tuple[str, Move, Point]: ...
222272

223273
class Line(NamedTuple):
224274
pt: Point
225275
@property
226-
def end_point(self): ...
227-
def render(self, gsd_registry, style, last_item, initial_point): ...
228-
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
276+
def end_point(self) -> Point: ...
277+
def render(
278+
self, gsd_registry: GraphicsStateDictRegistry, style: GraphicsStyle, last_item: _SupportsEndPoint, initial_point: Point
279+
) -> tuple[str, Self, Point]: ...
280+
def render_debug(
281+
self,
282+
gsd_registry: GraphicsStateDictRegistry,
283+
style: GraphicsStyle,
284+
last_item: _SupportsEndPoint,
285+
initial_point: Point,
286+
debug_stream: SupportsWrite[str],
287+
pfx: str,
288+
) -> tuple[str, Self, Point]: ...
229289

230290
class RelativeLine(NamedTuple):
231291
pt: Point
@@ -257,7 +317,7 @@ class BezierCurve(NamedTuple):
257317
c2: Point
258318
end: Point
259319
@property
260-
def end_point(self): ...
320+
def end_point(self) -> Point: ...
261321
def render(self, gsd_registry, style, last_item, initial_point): ...
262322
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
263323

@@ -272,7 +332,7 @@ class QuadraticBezierCurve(NamedTuple):
272332
ctrl: Point
273333
end: Point
274334
@property
275-
def end_point(self): ...
335+
def end_point(self) -> Point: ...
276336
def to_cubic_curve(self, start_point): ...
277337
def render(self, gsd_registry, style, last_item, initial_point): ...
278338
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
@@ -290,7 +350,7 @@ class Arc(NamedTuple):
290350
sweep: bool
291351
end: Point
292352
@staticmethod
293-
def subdivde_sweep(sweep_angle) -> Generator[Incomplete, None, None]: ...
353+
def subdivde_sweep(sweep_angle: Number) -> Generator[tuple[Point, Point, Point]]: ...
294354
def render(self, gsd_registry, style, last_item, initial_point): ...
295355
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
296356

@@ -337,10 +397,10 @@ class DrawingContext:
337397
def render_debug(self, gsd_registry, first_point, scale, height, starting_style, debug_stream): ...
338398

339399
class PaintedPath:
340-
def __init__(self, x: int = 0, y: int = 0) -> None: ...
400+
def __init__(self, x: Number = 0, y: Number = 0) -> None: ...
341401
def __deepcopy__(self, memo) -> Self: ...
342402
@property
343-
def style(self): ...
403+
def style(self) -> GraphicsStyle: ...
344404
@property
345405
def transform(self): ...
346406
@transform.setter
@@ -361,30 +421,34 @@ class PaintedPath:
361421
def transform_group(self, transform) -> Generator[Self]: ...
362422
def add_path_element(self, item, _copy: bool = True) -> None: ...
363423
def remove_last_path_element(self) -> None: ...
364-
def rectangle(self, x, y, w, h, rx: int = 0, ry: int = 0) -> Self: ...
365-
def circle(self, cx, cy, r) -> Self: ...
366-
def ellipse(self, cx, cy, rx, ry) -> Self: ...
367-
def move_to(self, x, y) -> Self: ...
368-
def move_relative(self, x, y) -> Self: ...
369-
def line_to(self, x, y) -> Self: ...
370-
def line_relative(self, dx, dy) -> Self: ...
371-
def horizontal_line_to(self, x) -> Self: ...
372-
def horizontal_line_relative(self, dx) -> Self: ...
373-
def vertical_line_to(self, y) -> Self: ...
374-
def vertical_line_relative(self, dy) -> Self: ...
375-
def curve_to(self, x1, y1, x2, y2, x3, y3) -> Self: ...
376-
def curve_relative(self, dx1, dy1, dx2, dy2, dx3, dy3) -> Self: ...
377-
def quadratic_curve_to(self, x1, y1, x2, y2) -> Self: ...
378-
def quadratic_curve_relative(self, dx1, dy1, dx2, dy2) -> Self: ...
379-
def arc_to(self, rx, ry, rotation, large_arc, positive_sweep, x, y) -> Self: ...
380-
def arc_relative(self, rx, ry, rotation, large_arc, positive_sweep, dx, dy) -> Self: ...
424+
def rectangle(self, x: Number, y: Number, w: Number, h: Number, rx: Number = 0, ry: Number = 0) -> Self: ...
425+
def circle(self, cx: Number, cy: Number, r: Number) -> Self: ...
426+
def ellipse(self, cx: Number, cy: Number, rx: Number, ry: Number) -> Self: ...
427+
def move_to(self, x: Number, y: Number) -> Self: ...
428+
def move_relative(self, x: Number, y: Number) -> Self: ...
429+
def line_to(self, x: Number, y: Number) -> Self: ...
430+
def line_relative(self, dx: Number, dy: Number) -> Self: ...
431+
def horizontal_line_to(self, x: Number) -> Self: ...
432+
def horizontal_line_relative(self, dx: Number) -> Self: ...
433+
def vertical_line_to(self, y: Number) -> Self: ...
434+
def vertical_line_relative(self, dy: Number) -> Self: ...
435+
def curve_to(self, x1: Number, y1: Number, x2: Number, y2: Number, x3: Number, y3: Number) -> Self: ...
436+
def curve_relative(self, dx1: Number, dy1: Number, dx2: Number, dy2: Number, dx3: Number, dy3: Number) -> Self: ...
437+
def quadratic_curve_to(self, x1: Number, y1: Number, x2: Number, y2: Number) -> Self: ...
438+
def quadratic_curve_relative(self, dx1: Number, dy1: Number, dx2: Number, dy2: Number) -> Self: ...
439+
def arc_to(
440+
self, rx: Number, ry: Number, rotation: Number, large_arc: bool, positive_sweep: bool, x: Number, y: Number
441+
) -> Self: ...
442+
def arc_relative(
443+
self, rx: Number, ry: Number, rotation: Number, large_arc: bool, positive_sweep: bool, dx: Number, dy: Number
444+
) -> Self: ...
381445
def close(self) -> None: ...
382446
def render(self, gsd_registry, style, last_item, initial_point, debug_stream=None, pfx=None): ...
383447
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
384448

385449
class ClippingPath(PaintedPath):
386-
paint_rule: Incomplete
387-
def __init__(self, x: int = 0, y: int = 0) -> None: ...
450+
paint_rule: PathPaintRule
451+
def __init__(self, x: Number = 0, y: Number = 0) -> None: ...
388452
def render(self, gsd_registry, style, last_item, initial_point, debug_stream=None, pfx=None): ...
389453
def render_debug(self, gsd_registry, style, last_item, initial_point, debug_stream, pfx): ...
390454

stubs/fpdf2/fpdf/text_region.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Extents(NamedTuple):
1414
class TextRegionMixin:
1515
def __init__(self, *args, **kwargs) -> None: ...
1616
def register_text_region(self, region) -> None: ...
17-
def is_current_text_region(self, region): ...
17+
def is_current_text_region(self, region) -> bool: ...
1818
def clear_text_region(self) -> None: ...
1919

2020
class LineWrapper(NamedTuple):

0 commit comments

Comments
 (0)