]> Repositories - hackapet/Adafruit_Blinka_Displayio.git/blob - displayio/_area.py
Start splitting display functions into display core
[hackapet/Adafruit_Blinka_Displayio.git] / displayio / _area.py
1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
2 # SPDX-FileCopyrightText: 2021 James Carr
3 #
4 # SPDX-License-Identifier: MIT
5
6 """
7 `displayio._area`
8 ================================================================================
9
10 Area for Blinka Displayio
11
12 **Software and Dependencies:**
13
14 * Adafruit Blinka:
15   https://github.com/adafruit/Adafruit_Blinka/releases
16
17 * Author(s): James Carr, Melissa LeBlanc-Williams
18
19 """
20
21 from __future__ import annotations
22
23 __version__ = "0.0.0-auto.0"
24 __repo__ = "https://github.com/adafruit/Adafruit_Blinka_Displayio.git"
25
26 class Area:
27     # pylint: disable=invalid-name,missing-function-docstring
28     def __init__(self, x1: int = 0, y1: int = 0, x2: int = 0, y2: int = 0):
29         self.x1 = x1
30         self.y1 = y1
31         self.x2 = x2
32         self.y2 = y2
33         self.next = None
34
35     def __str__(self):
36         return f"Area TL({self.x1},{self.y1}) BR({self.x2},{self.y2})"
37
38     def _copy_into(self, dst) -> None:
39         dst.x1 = self.x1
40         dst.y1 = self.y1
41         dst.x2 = self.x2
42         dst.y2 = self.y2
43
44     def _scale(self, scale: int) -> None:
45         self.x1 *= scale
46         self.y1 *= scale
47         self.x2 *= scale
48         self.y2 *= scale
49
50     def _shift(self, dx: int, dy: int) -> None:
51         self.x1 += dx
52         self.y1 += dy
53         self.x2 += dx
54         self.y2 += dy
55
56     def _compute_overlap(self, other, overlap) -> bool:
57         a = self
58         overlap.x1 = max(a.x1, other.x1)
59         overlap.x2 = min(a.x2, other.x2)
60
61         if overlap.x1 >= overlap.x2:
62             return False
63
64         overlap.y1 = max(a.y1, other.y1)
65         overlap.y2 = min(a.y2, other.y2)
66
67         return overlap.y1 < overlap.y2
68
69     def _empty(self):
70         return (self.x1 == self.x2) or (self.y1 == self.y2)
71
72     def _canon(self):
73         if self.x1 > self.x2:
74             self.x1, self.x2 = self.x2, self.x1
75         if self.y1 > self.y2:
76             self.y1, self.y2 = self.y2, self.y1
77
78     def _union(self, other, union):
79         # pylint: disable=protected-access
80         if self._empty():
81             self._copy_into(union)
82             return
83         if other._empty():
84             other._copy_into(union)
85             return
86
87         union.x1 = min(self.x1, other.x1)
88         union.y1 = min(self.y1, other.y1)
89         union.x2 = max(self.x2, other.x2)
90         union.y2 = max(self.y2, other.y2)
91
92     def width(self) -> int:
93         return self.x2 - self.x1
94
95     def height(self) -> int:
96         return self.y2 - self.y1
97
98     def size(self) -> int:
99         return self.width() * self.height()
100
101     def __eq__(self, other):
102         if not isinstance(other, Area):
103             return False
104
105         return (
106             self.x1 == other.x1
107             and self.y1 == other.y1
108             and self.x2 == other.x2
109             and self.y2 == other.y2
110         )
111
112     @staticmethod
113     def _transform_within(
114         mirror_x: bool,
115         mirror_y: bool,
116         transpose_xy: bool,
117         original: Area,
118         whole: Area,
119         transformed: Area,
120     ):
121         # pylint: disable=too-many-arguments
122         # Original and whole must be in the same coordinate space.
123         if mirror_x:
124             transformed.x1 = whole.x1 + (whole.x2 - original.x2)
125             transformed.x2 = whole.x2 - (original.x1 - whole.x1)
126         else:
127             transformed.x1 = original.x1
128             transformed.x2 = original.x2
129
130         if mirror_y:
131             transformed.y1 = whole.y1 + (whole.y2 - original.y2)
132             transformed.y2 = whole.y2 - (original.y1 - whole.y1)
133         else:
134             transformed.y1 = original.y1
135             transformed.y2 = original.y2
136
137         if transpose_xy:
138             y1 = transformed.y1
139             y2 = transformed.y2
140             transformed.y1 = whole.y1 + (transformed.x1 - whole.x1)
141             transformed.y2 = whole.y1 + (transformed.x2 - whole.x1)
142             transformed.x1 = whole.x1 + (y1 - whole.y1)
143             transformed.x2 = whole.x1 + (y2 - whole.y1)