libDaisy
Hardware Library for Daisy
Loading...
Searching...
No Matches
display.h
Go to the documentation of this file.
1#pragma once
2#ifndef DSY_DISPLAY_H
3#define DSY_DISPLAY_H
4#include <cmath>
5#include "util/oled_fonts.h"
6#include "daisy_core.h"
7#include "graphics_common.h"
8
9#ifndef deg2rad
10#define deg2rad(deg) ((deg)*3.141592 / 180.0)
11#endif
12
13namespace daisy
14{
20{
21 public:
24
25 virtual uint16_t Height() const = 0;
26 virtual uint16_t Width() const = 0;
27
29 {
30 return Rectangle(int16_t(Width()), int16_t(Height()));
31 }
32
33
34 size_t CurrentX() { return currentX_; };
35 size_t CurrentY() { return currentY_; };
36
41 virtual void Fill(bool on) = 0;
42
49 virtual void DrawPixel(uint_fast8_t x, uint_fast8_t y, bool on) = 0;
50
59 virtual void DrawLine(uint_fast8_t x1,
63 bool on)
64 = 0;
65
75 virtual void DrawRect(uint_fast8_t x1,
79 bool on,
80 bool fill = false)
81 = 0;
82
89 void DrawRect(const Rectangle& rect, bool on, bool fill = false)
90 {
91 DrawRect(rect.GetX(),
92 rect.GetY(),
93 rect.GetRight(),
94 rect.GetBottom(),
95 on,
96 fill);
97 }
98
108 virtual void DrawArc(uint_fast8_t x,
109 uint_fast8_t y,
113 bool on)
114 = 0;
115
123 void
125 {
126 DrawArc(x, y, radius, 0, 360, on);
127 };
128
137 virtual char WriteChar(char ch, FontDef font, bool on) = 0;
138
148 virtual char WriteString(const char* str, FontDef font, bool on) = 0;
149
159 virtual Rectangle WriteStringAligned(const char* str,
160 const FontDef& font,
163 bool on)
164 = 0;
165
172 {
173 currentX_ = (x >= Width()) ? Width() - 1 : x;
174 currentY_ = (y >= Height()) ? Height() - 1 : y;
175 }
176
181 virtual void Update() = 0;
182
183 protected:
186};
187
214template <class ChildType>
216{
217 public:
220
225 bool on) override
226 {
229 int_fast16_t signX = ((x1 < x2) ? 1 : -1);
230 int_fast16_t signY = ((y1 < y2) ? 1 : -1);
233
234 // If we write "ChildType::DrawPixel(x2, y2, on);", we end up with
235 // all sorts of weird compiler errors when the Child class is a template
236 // class. The only way around this is to use this very verbose syntax:
237 ((ChildType*)(this))->ChildType::DrawPixel(x2, y2, on);
238
239 while((x1 != x2) || (y1 != y2))
240 {
241 ((ChildType*)(this))->ChildType::DrawPixel(x1, y1, on);
242 error2 = error * 2;
243 if(error2 > -deltaY)
244 {
245 error -= deltaY;
246 x1 += signX;
247 }
248
249 if(error2 < deltaX)
250 {
251 error += deltaX;
252 y1 += signY;
253 }
254 }
255 }
256
261 bool on,
262 bool fill = false) override
263 {
264 if(fill)
265 {
266 for(uint_fast8_t x = x1; x <= x2; x++)
267 {
268 for(uint_fast8_t y = y1; y <= y2; y++)
269 {
270 ((ChildType*)(this))->ChildType::DrawPixel(x, y, on);
271 }
272 }
273 }
274 else
275 {
276 ((ChildType*)(this))->ChildType::DrawLine(x1, y1, x2, y1, on);
277 ((ChildType*)(this))->ChildType::DrawLine(x2, y1, x2, y2, on);
278 ((ChildType*)(this))->ChildType::DrawLine(x2, y2, x1, y2, on);
279 ((ChildType*)(this))->ChildType::DrawLine(x1, y2, x1, y1, on);
280 }
281 }
282
284 uint_fast8_t y,
288 bool on) override
289 {
290 // Values to calculate the circle
292
293 // Temporary values to speed up comparisons
294 float t_sxy, t_syx, t_sxny, t_synx;
295 float t_exy, t_eyx, t_exny, t_eynx;
296
298 float start_x, start_y, end_x, end_y;
299
300 bool d1, d2, d3, d4;
301
302 d1 = d2 = d3 = d4 = true;
303
304 bool circle = false;
305
306 if(sweep < 0)
307 {
309 sweep = -sweep;
310 }
311
314
319
320 // Check if start and endpoint are very near
321 if((end_x - start_x) * (end_x - start_x)
322 + (end_y - start_y) * (end_y - start_y)
323 < 2.0f)
324 {
325 if(sweep > 180)
326 circle = true;
327 else
328 // Nothing to draw
329 return;
330 }
331
332 t_x = -radius;
333 t_y = 0;
334 err = 2 - 2 * radius;
335
336 do
337 {
338 if(!circle)
339 {
340 t_sxy = start_x * t_y;
341 t_syx = start_y * t_x;
342 t_sxny = start_x * -t_y;
343 t_synx = start_y * -t_x;
344 t_exy = end_x * t_y;
345 t_eyx = end_y * t_x;
346 t_exny = end_x * -t_y;
347 t_eynx = end_y * -t_x;
348
349 if(sweep > 180)
350 {
351 d1 = (t_sxy - t_synx < 0 || t_exy - t_eynx > 0);
352 d2 = (t_sxy - t_syx < 0 || t_exy - t_eyx > 0);
353 d3 = (t_sxny - t_syx < 0 || t_exny - t_eyx > 0);
354 d4 = (t_sxny - t_synx < 0 || t_exny - t_eynx > 0);
355 }
356 else
357 {
358 d1 = (t_sxy - t_synx < 0 && t_exy - t_eynx > 0);
359 d2 = (t_sxy - t_syx < 0 && t_exy - t_eyx > 0);
360 d3 = (t_sxny - t_syx < 0 && t_exny - t_eyx > 0);
361 d4 = (t_sxny - t_synx < 0 && t_exny - t_eynx > 0);
362 }
363 }
364
365 if(d1)
366 ((ChildType*)(this))
367 ->ChildType::DrawPixel(x - t_x, y + t_y, on);
368 if(d2)
369 ((ChildType*)(this))
370 ->ChildType::DrawPixel(x + t_x, y + t_y, on);
371 if(d3)
372 ((ChildType*)(this))
373 ->ChildType::DrawPixel(x + t_x, y - t_y, on);
374 if(d4)
375 ((ChildType*)(this))
376 ->ChildType::DrawPixel(x - t_x, y - t_y, on);
377
378 e2 = err;
379 if(e2 <= t_y)
380 {
381 t_y++;
382 err = err + (t_y * 2 + 1);
383 if(-t_x == t_y && e2 <= t_x)
384 {
385 e2 = 0;
386 }
387 }
388 if(e2 > t_x)
389 {
390 t_x++;
391 err = err + (t_x * 2 + 1);
392 }
393 } while(t_x <= 0);
394 }
395
396 char WriteChar(char ch, FontDef font, bool on) override
397 {
398 uint32_t i, b, j;
399
400 // Check if character is valid
401 if(ch < 32 || ch > 126)
402 return 0;
403
404 // Check remaining space on current line
405 if(Width() < (currentX_ + font.FontWidth)
406 || Height() < (currentY_ + font.FontHeight))
407 {
408 // Not enough space on current line
409 return 0;
410 }
411
412 // Use the font to write
413 for(i = 0; i < font.FontHeight; i++)
414 {
415 b = font.data[(ch - 32) * font.FontHeight + i];
416 for(j = 0; j < font.FontWidth; j++)
417 {
418 if((b << j) & 0x8000)
419 {
420 ((ChildType*)(this))
421 ->ChildType::DrawPixel(
422 currentX_ + j, (currentY_ + i), on);
423 }
424 else
425 {
426 ((ChildType*)(this))
427 ->ChildType::DrawPixel(
428 currentX_ + j, (currentY_ + i), !on);
429 }
430 }
431 }
432
433 // The current space is now taken
434 SetCursor(currentX_ + font.FontWidth, currentY_);
435
436 // Return written char for validation
437 return ch;
438 }
439
440 char WriteString(const char* str, FontDef font, bool on) override
441 {
442 // Write until null-byte
443 while(*str)
444 {
445 if(((ChildType*)(this))->ChildType::WriteChar(*str, font, on)
446 != *str)
447 {
448 // Char could not be written
449 return *str;
450 }
451
452 // Next char
453 str++;
454 }
455
456 // Everything ok
457 return *str;
458 }
459
461 const FontDef& font,
464 bool on) override
465 {
466 const auto alignedRect
467 = GetTextRect(str, font).AlignedWithin(boundingBox, alignment);
468 SetCursor(alignedRect.GetX(), alignedRect.GetY());
469 ((ChildType*)(this))->ChildType::WriteString(str, font, on);
470 return alignedRect;
471 }
472
473 private:
474 uint32_t strlen(const char* string)
475 {
476 uint32_t result = 0;
477 while(*string++ != '\0')
478 result++;
479 return result;
480 }
481
482 Rectangle GetTextRect(const char* text, const FontDef& font)
483 {
484 const auto numChars = strlen(text);
485 return {int16_t(numChars * font.FontWidth), font.FontHeight};
486 }
487};
488
489} // namespace daisy
490
491#endif
Definition leddriver.h:33
Definition display.h:20
virtual void Fill(bool on)=0
virtual void DrawRect(uint_fast8_t x1, uint_fast8_t y1, uint_fast8_t x2, uint_fast8_t y2, bool on, bool fill=false)=0
uint16_t currentY_
Definition display.h:185
virtual void DrawLine(uint_fast8_t x1, uint_fast8_t y1, uint_fast8_t x2, uint_fast8_t y2, bool on)=0
virtual void DrawPixel(uint_fast8_t x, uint_fast8_t y, bool on)=0
virtual char WriteChar(char ch, FontDef font, bool on)=0
virtual uint16_t Width() const =0
void DrawRect(const Rectangle &rect, bool on, bool fill=false)
Definition display.h:89
Rectangle GetBounds() const
Definition display.h:28
virtual void DrawArc(uint_fast8_t x, uint_fast8_t y, uint_fast8_t radius, int_fast16_t start_angle, int_fast16_t sweep, bool on)=0
size_t CurrentY()
Definition display.h:35
virtual char WriteString(const char *str, FontDef font, bool on)=0
virtual uint16_t Height() const =0
size_t CurrentX()
Definition display.h:34
virtual Rectangle WriteStringAligned(const char *str, const FontDef &font, Rectangle boundingBox, Alignment alignment, bool on)=0
virtual ~OneBitGraphicsDisplay()
Definition display.h:23
void SetCursor(uint16_t x, uint16_t y)
Definition display.h:171
OneBitGraphicsDisplay()
Definition display.h:22
uint16_t currentX_
Definition display.h:184
void DrawCircle(uint_fast8_t x, uint_fast8_t y, uint_fast8_t radius, bool on)
Definition display.h:124
Definition display.h:216
char WriteString(const char *str, FontDef font, bool on) override
Definition display.h:440
char WriteChar(char ch, FontDef font, bool on) override
Definition display.h:396
OneBitGraphicsDisplayImpl()
Definition display.h:218
virtual ~OneBitGraphicsDisplayImpl()
Definition display.h:219
Rectangle WriteStringAligned(const char *str, const FontDef &font, Rectangle boundingBox, Alignment alignment, bool on) override
Definition display.h:460
void DrawLine(uint_fast8_t x1, uint_fast8_t y1, uint_fast8_t x2, uint_fast8_t y2, bool on) override
Definition display.h:221
void DrawArc(uint_fast8_t x, uint_fast8_t y, uint_fast8_t radius, int_fast16_t start_angle, int_fast16_t sweep, bool on) override
Definition display.h:283
void DrawRect(uint_fast8_t x1, uint_fast8_t y1, uint_fast8_t x2, uint_fast8_t y2, bool on, bool fill=false) override
Definition display.h:257
Definition graphics_common.h:22
Rectangle AlignedWithin(const Rectangle &other, Alignment alignment) const
Definition graphics_common.h:209
#define deg2rad(deg)
Definition display.h:10
Hardware defines and helpers for daisy field platform.
Definition index.h:2
Alignment
Definition graphics_common.h:9
Definition oled_fonts.h:17
uint8_t FontHeight
Definition oled_fonts.h:19
const uint8_t FontWidth
Definition oled_fonts.h:18