@@ -68,6 +68,16 @@ def get_pixel(framebuf, x, y):
68
68
offset = 7 - x & 0x07
69
69
return (framebuf .buf [index ] >> offset ) & 0x01
70
70
71
+ @staticmethod
72
+ def fill (framebuf , color ):
73
+ """completely fill/clear the buffer with a color"""
74
+ if color :
75
+ fill = 0xFF
76
+ else :
77
+ fill = 0x00
78
+ for i in range (len (framebuf .buf )):
79
+ framebuf .buf [i ] = fill
80
+
71
81
@staticmethod
72
82
def fill_rect (framebuf , x , y , width , height , color ):
73
83
"""Draw a rectangle at the given location, size and color. The ``fill_rect`` method draws
@@ -96,6 +106,16 @@ def get_pixel(framebuf, x, y):
96
106
offset = y & 0x07
97
107
return (framebuf .buf [index ] >> offset ) & 0x01
98
108
109
+ @staticmethod
110
+ def fill (framebuf , color ):
111
+ """completely fill/clear the buffer with a color"""
112
+ if color :
113
+ fill = 0xFF
114
+ else :
115
+ fill = 0x00
116
+ for i in range (len (framebuf .buf )):
117
+ framebuf .buf [i ] = fill
118
+
99
119
@staticmethod
100
120
def fill_rect (framebuf , x , y , width , height , color ):
101
121
"""Draw a rectangle at the given location, size and color. The ``fill_rect`` method draws
@@ -110,36 +130,6 @@ def fill_rect(framebuf, x, y, width, height, color):
110
130
y += 1
111
131
height -= 1
112
132
113
-
114
- class RGB565Format :
115
- """RGB565Format"""
116
- @staticmethod
117
- def set_pixel (framebuf , x , y , color ):
118
- """Set a given pixel to a color."""
119
- index = (x + y * framebuf .stride ) * 2
120
- framebuf .buf [index ] = (color >> 8 ) & 0xFF
121
- framebuf .buf [index + 1 ] = color & 0xFF
122
-
123
- @staticmethod
124
- def get_pixel (framebuf , x , y ):
125
- """Get the color of a given pixel"""
126
- index = (x + y * framebuf .stride ) * 2
127
- return (framebuf .buf [index ] << 8 ) | framebuf .buf [index + 1 ]
128
-
129
- @staticmethod
130
- def fill_rect (framebuf , x , y , width , height , color ):
131
- # pylint: disable=too-many-arguments
132
- """Draw a rectangle at the given location, size and color. The ``fill_rect`` method draws
133
- both the outline and interior."""
134
- while height > 0 :
135
- for w_w in range (width ):
136
- index = (w_w + x + y * framebuf .stride ) * 2
137
- framebuf .buf [index ] = (color >> 8 ) & 0xFF
138
- framebuf .buf [index + 1 ] = color & 0xFF
139
- y += 1
140
- height -= 1
141
-
142
-
143
133
class FrameBuffer :
144
134
"""FrameBuffer object.
145
135
@@ -171,31 +161,44 @@ def __init__(self, buf, width, height, buf_format=MVLSB, stride=None):
171
161
self .format = MVLSBFormat ()
172
162
elif buf_format == MHMSB :
173
163
self .format = MHMSBFormat ()
174
- elif buf_format == RGB565 :
175
- self .format = RGB565Format ()
176
164
else :
177
165
raise ValueError ('invalid format' )
166
+ self ._rotation = 0
167
+
168
+ @property
169
+ def rotation (self ):
170
+ """The rotation setting of the display, can be one of (0, 1, 2, 3)"""
171
+ return self ._rotation
172
+
173
+ @rotation .setter
174
+ def rotation (self , val ):
175
+ if not val in (0 , 1 , 2 , 3 ):
176
+ raise RuntimeError ("Bad rotation setting" )
177
+ self ._rotation = val
178
178
179
179
def fill (self , color ):
180
180
"""Fill the entire FrameBuffer with the specified color."""
181
- self .format .fill_rect (self , 0 , 0 , self . width , self . height , color )
181
+ self .format .fill (self , color )
182
182
183
183
def fill_rect (self , x , y , width , height , color ):
184
184
"""Draw a rectangle at the given location, size and color. The ``fill_rect`` method draws
185
185
both the outline and interior."""
186
186
# pylint: disable=too-many-arguments, too-many-boolean-expressions
187
- if width < 1 or height < 1 or (x + width ) <= 0 or (y + height ) <= 0 or y >= self .height \
188
- or x >= self .width :
189
- return
190
- x_end = min (self .width , x + width )
191
- y_end = min (self .height , y + height )
192
- x = max (x , 0 )
193
- y = max (y , 0 )
194
- self .format .fill_rect (self , x , y , x_end - x , y_end - y , color )
187
+ self .rect (x , y , width , height , color , fill = True )
195
188
196
189
def pixel (self , x , y , color = None ):
197
190
"""If ``color`` is not given, get the color value of the specified pixel. If ``color`` is
198
191
given, set the specified pixel to the given color."""
192
+ if self .rotation == 1 :
193
+ x , y = y , x
194
+ x = self .width - x - 1
195
+ if self .rotation == 2 :
196
+ x = self .width - x - 1
197
+ y = self .height - y - 1
198
+ if self .rotation == 3 :
199
+ x , y = y , x
200
+ y = self .height - y - 1
201
+
199
202
if x < 0 or x >= self .width or y < 0 or y >= self .height :
200
203
return None
201
204
if color is None :
@@ -205,20 +208,43 @@ def pixel(self, x, y, color=None):
205
208
206
209
def hline (self , x , y , width , color ):
207
210
"""Draw a horizontal line up to a given length."""
208
- self .fill_rect (x , y , width , 1 , color )
211
+ self .rect (x , y , width , 1 , color , fill = True )
209
212
210
213
def vline (self , x , y , height , color ):
211
214
"""Draw a vertical line up to a given length."""
212
- self .fill_rect (x , y , 1 , height , color )
215
+ self .rect (x , y , 1 , height , color , fill = True )
213
216
214
- def rect (self , x , y , width , height , color ):
217
+ def rect (self , x , y , width , height , color , * , fill = False ):
215
218
"""Draw a rectangle at the given location, size and color. The ```rect``` method draws only
216
219
a 1 pixel outline."""
217
220
# pylint: disable=too-many-arguments
218
- self .fill_rect (x , y , width , 1 , color )
219
- self .fill_rect (x , y + height - 1 , width , 1 , color )
220
- self .fill_rect (x , y , 1 , height , color )
221
- self .fill_rect (x + width - 1 , y , 1 , height , color )
221
+ if self .rotation == 1 :
222
+ x , y = y , x
223
+ width , height = height , width
224
+ x = self .width - x - width
225
+ if self .rotation == 2 :
226
+ x = self .width - x - width
227
+ y = self .height - y - height
228
+ if self .rotation == 3 :
229
+ x , y = y , x
230
+ width , height = height , width
231
+ y = self .height - y - height
232
+
233
+ # pylint: disable=too-many-boolean-expressions
234
+ if width < 1 or height < 1 or (x + width ) <= 0 or (y + height ) <= 0 or \
235
+ y >= self .height or x >= self .width :
236
+ return
237
+ x_end = min (self .width - 1 , x + width - 1 )
238
+ y_end = min (self .height - 1 , y + height - 1 )
239
+ x = max (x , 0 )
240
+ y = max (y , 0 )
241
+ if fill :
242
+ self .format .fill_rect (self , x , y , x_end - x + 1 , y_end - y + 1 , color )
243
+ else :
244
+ self .format .fill_rect (self , x , y , x_end - x + 1 , 1 , color )
245
+ self .format .fill_rect (self , x , y , 1 , y_end - y + 1 , color )
246
+ self .format .fill_rect (self , x , y_end , x_end - x + 1 , 1 , color )
247
+ self .format .fill_rect (self , x_end , y , 1 , y_end - y + 1 , color )
222
248
223
249
def line (self , x_0 , y_0 , x_1 , y_1 , color ):
224
250
# pylint: disable=too-many-arguments
@@ -356,14 +382,17 @@ def draw_char(self, char, x, y, framebuffer, color):
356
382
# pylint: disable=too-many-arguments
357
383
"""Draw one character at position (x,y) to a framebuffer in a given color"""
358
384
# Don't draw the character if it will be clipped off the visible area.
359
- if x < - self .font_width or x >= framebuffer .width or \
360
- y < - self .font_height or y >= framebuffer .height :
361
- return
385
+ # if x < -self.font_width or x >= framebuffer.width or \
386
+ # y < -self.font_height or y >= framebuffer.height:
387
+ # return
362
388
# Go through each column of the character.
363
389
for char_x in range (self .font_width ):
364
390
# Grab the byte for the current column of font data.
365
391
self ._font .seek (2 + (ord (char ) * self .font_width ) + char_x )
366
- line = struct .unpack ('B' , self ._font .read (1 ))[0 ]
392
+ try :
393
+ line = struct .unpack ('B' , self ._font .read (1 ))[0 ]
394
+ except RuntimeError :
395
+ continue # maybe character isnt there? go to next
367
396
# Go through each row in the column byte.
368
397
for char_y in range (self .font_height ):
369
398
# Draw a pixel for each bit that's flipped on.
0 commit comments