|
6 | 6 | from __future__ import annotations |
7 | 7 |
|
8 | 8 | import enum |
9 | | -from typing import Any, Final |
| 9 | +from typing import Any, Final, Sequence |
10 | 10 |
|
11 | 11 | import numpy as np |
12 | 12 | from numpy.typing import NDArray |
@@ -594,59 +594,78 @@ def draw_line(self, start: tuple[float, float], end: tuple[float, float]) -> Non |
594 | 594 | _check(lib.SDL_RenderDrawLineF(self.p, x1, y1, x2, y2)) |
595 | 595 |
|
596 | 596 | @staticmethod |
597 | | - def _convert_array(array: NDArray[np.number]) -> NDArray[np.intc] | NDArray[np.float32]: |
598 | | - """Convert ndarray for a SDL function expecting a C contiguous array of either intc or float32.""" |
599 | | - if array.dtype in (np.intc, np.int8, np.int16, np.int32, np.uint8, np.uint16): |
600 | | - return np.ascontiguousarray(array, np.intc) |
601 | | - return np.ascontiguousarray(array, np.float32) |
| 597 | + def _convert_array( |
| 598 | + array: NDArray[np.number] | Sequence[Sequence[float]], item_length: int |
| 599 | + ) -> NDArray[np.intc] | NDArray[np.float32]: |
| 600 | + """Convert ndarray for a SDL function expecting a C contiguous array of either intc or float32. |
602 | 601 |
|
603 | | - def fill_rects(self, rects: NDArray[np.number]) -> None: |
| 602 | + Array shape is enforced to be (n, item_length) |
| 603 | + """ |
| 604 | + if getattr(array, "dtype", None) in (np.intc, np.int8, np.int16, np.int32, np.uint8, np.uint16): |
| 605 | + out = np.ascontiguousarray(array, np.intc) |
| 606 | + else: |
| 607 | + out = np.ascontiguousarray(array, np.float32) |
| 608 | + if len(out.shape) != 2: # noqa: PLR2004 |
| 609 | + msg = f"Array must have 2 axes, but shape is {out.shape!r}" |
| 610 | + raise TypeError(msg) |
| 611 | + if out.shape[1] != item_length: |
| 612 | + msg = f"Array shape[1] must be {item_length}, but shape is {out.shape!r}" |
| 613 | + raise TypeError(msg) |
| 614 | + return out |
| 615 | + |
| 616 | + def fill_rects(self, rects: NDArray[np.number] | Sequence[tuple[float, float, float, float]]) -> None: |
604 | 617 | """Fill multiple rectangles from an array. |
605 | 618 |
|
| 619 | + Args: |
| 620 | + rects: A sequence or array of (x, y, width, height) rectangles. |
| 621 | +
|
606 | 622 | .. versionadded:: 13.5 |
607 | 623 | """ |
608 | | - assert len(rects.shape) == 2 # noqa: PLR2004 |
609 | | - assert rects.shape[1] == 4 # noqa: PLR2004 |
610 | | - rects = self._convert_array(rects) |
| 624 | + rects = self._convert_array(rects, item_length=4) |
611 | 625 | if rects.dtype == np.intc: |
612 | 626 | _check(lib.SDL_RenderFillRects(self.p, tcod.ffi.from_buffer("SDL_Rect*", rects), rects.shape[0])) |
613 | 627 | return |
614 | 628 | _check(lib.SDL_RenderFillRectsF(self.p, tcod.ffi.from_buffer("SDL_FRect*", rects), rects.shape[0])) |
615 | 629 |
|
616 | | - def draw_rects(self, rects: NDArray[np.number]) -> None: |
| 630 | + def draw_rects(self, rects: NDArray[np.number] | Sequence[tuple[float, float, float, float]]) -> None: |
617 | 631 | """Draw multiple outlined rectangles from an array. |
618 | 632 |
|
| 633 | + Args: |
| 634 | + rects: A sequence or array of (x, y, width, height) rectangles. |
| 635 | +
|
619 | 636 | .. versionadded:: 13.5 |
620 | 637 | """ |
| 638 | + rects = self._convert_array(rects, item_length=4) |
621 | 639 | assert len(rects.shape) == 2 # noqa: PLR2004 |
622 | 640 | assert rects.shape[1] == 4 # noqa: PLR2004 |
623 | | - rects = self._convert_array(rects) |
624 | 641 | if rects.dtype == np.intc: |
625 | 642 | _check(lib.SDL_RenderDrawRects(self.p, tcod.ffi.from_buffer("SDL_Rect*", rects), rects.shape[0])) |
626 | 643 | return |
627 | 644 | _check(lib.SDL_RenderDrawRectsF(self.p, tcod.ffi.from_buffer("SDL_FRect*", rects), rects.shape[0])) |
628 | 645 |
|
629 | | - def draw_points(self, points: NDArray[np.number]) -> None: |
| 646 | + def draw_points(self, points: NDArray[np.number] | Sequence[tuple[float, float]]) -> None: |
630 | 647 | """Draw an array of points. |
631 | 648 |
|
| 649 | + Args: |
| 650 | + points: A sequence or array of (x, y) points. |
| 651 | +
|
632 | 652 | .. versionadded:: 13.5 |
633 | 653 | """ |
634 | | - assert len(points.shape) == 2 # noqa: PLR2004 |
635 | | - assert points.shape[1] == 2 # noqa: PLR2004 |
636 | | - points = self._convert_array(points) |
| 654 | + points = self._convert_array(points, item_length=2) |
637 | 655 | if points.dtype == np.intc: |
638 | 656 | _check(lib.SDL_RenderDrawPoints(self.p, tcod.ffi.from_buffer("SDL_Point*", points), points.shape[0])) |
639 | 657 | return |
640 | 658 | _check(lib.SDL_RenderDrawPointsF(self.p, tcod.ffi.from_buffer("SDL_FPoint*", points), points.shape[0])) |
641 | 659 |
|
642 | | - def draw_lines(self, points: NDArray[np.intc | np.float32]) -> None: |
| 660 | + def draw_lines(self, points: NDArray[np.number] | Sequence[tuple[float, float]]) -> None: |
643 | 661 | """Draw a connected series of lines from an array. |
644 | 662 |
|
| 663 | + Args: |
| 664 | + points: A sequence or array of (x, y) points. |
| 665 | +
|
645 | 666 | .. versionadded:: 13.5 |
646 | 667 | """ |
647 | | - assert len(points.shape) == 2 # noqa: PLR2004 |
648 | | - assert points.shape[1] == 2 # noqa: PLR2004 |
649 | | - points = self._convert_array(points) |
| 668 | + points = self._convert_array(points, item_length=2) |
650 | 669 | if points.dtype == np.intc: |
651 | 670 | _check(lib.SDL_RenderDrawLines(self.p, tcod.ffi.from_buffer("SDL_Point*", points), points.shape[0] - 1)) |
652 | 671 | return |
|
0 commit comments