libDaisy
Hardware Library for Daisy
Loading...
Searching...
No Matches
color_display.h
Go to the documentation of this file.
1#pragma once
2#include <cmath>
3#include "util/oled_fonts.h"
4#include "daisy_core.h"
5#include "graphics_common.h"
6
7#ifndef deg2rad
8#define deg2rad(deg) ((deg)*3.141592 / 180.0)
9#endif
10
11namespace daisy
12{
18{
19 public:
22
23 virtual uint16_t Height() const = 0;
24 virtual uint16_t Width() const = 0;
25
27 {
28 return Rectangle(int16_t(Width()), int16_t(Height()));
29 }
30
31
32 size_t CurrentX() { return currentX_; };
33 size_t CurrentY() { return currentY_; };
34
39 virtual void Fill(bool on) = 0;
40
47 virtual void DrawPixel(uint_fast8_t x, uint_fast8_t y, bool on) = 0;
48
56
64
73 virtual void DrawLine(uint_fast8_t x1,
77 bool on)
78 = 0;
79
89 virtual void DrawRect(uint_fast8_t x1,
93 bool on,
94 bool fill = false)
95 = 0;
96
103 void DrawRect(const Rectangle& rect, bool on, bool fill = false)
104 {
105 DrawRect(rect.GetX(),
106 rect.GetY(),
107 rect.GetRight(),
108 rect.GetBottom(),
109 on,
110 fill);
111 }
112
122 virtual void DrawArc(uint_fast8_t x,
123 uint_fast8_t y,
127 bool on)
128 = 0;
129
137 void
139 {
140 DrawArc(x, y, radius, 0, 360, on);
141 };
142
151 virtual char WriteChar(char ch, FontDef font, bool on) = 0;
152
162 virtual char WriteString(const char* str, FontDef font, bool on) = 0;
163
173 virtual Rectangle WriteStringAligned(const char* str,
174 const FontDef& font,
177 bool on)
178 = 0;
179
186 {
187 currentX_ = (x >= Width()) ? Width() - 1 : x;
188 currentY_ = (y >= Height()) ? Height() - 1 : y;
189 }
190
195 virtual void Update() = 0;
196
197 protected:
200};
201
228template <class ChildType>
230{
231 public:
234
239 bool on) override
240 {
243 int_fast16_t signX = ((x1 < x2) ? 1 : -1);
244 int_fast16_t signY = ((y1 < y2) ? 1 : -1);
247
248 // If we write "ChildType::DrawPixel(x2, y2, on);", we end up with
249 // all sorts of weird compiler errors when the Child class is a template
250 // class. The only way around this is to use this very verbose syntax:
251 ((ChildType*)(this))->ChildType::DrawPixel(x2, y2, on);
252
253 while((x1 != x2) || (y1 != y2))
254 {
255 ((ChildType*)(this))->ChildType::DrawPixel(x1, y1, on);
256 error2 = error * 2;
257 if(error2 > -deltaY)
258 {
259 error -= deltaY;
260 x1 += signX;
261 }
262
263 if(error2 < deltaX)
264 {
265 error += deltaX;
266 y1 += signY;
267 }
268 }
269 }
270
275 bool on,
276 bool fill = false) override
277 {
278 if(fill)
279 {
280 for(uint_fast8_t x = x1; x <= x2; x++)
281 {
282 for(uint_fast8_t y = y1; y <= y2; y++)
283 {
284 ((ChildType*)(this))->ChildType::DrawPixel(x, y, on);
285 }
286 }
287 }
288 else
289 {
290 ((ChildType*)(this))->ChildType::DrawLine(x1, y1, x2, y1, on);
291 ((ChildType*)(this))->ChildType::DrawLine(x2, y1, x2, y2, on);
292 ((ChildType*)(this))->ChildType::DrawLine(x2, y2, x1, y2, on);
293 ((ChildType*)(this))->ChildType::DrawLine(x1, y2, x1, y1, on);
294 }
295 }
296
298 uint_fast8_t y,
302 bool on) override
303 {
304 // Values to calculate the circle
306
307 // Temporary values to speed up comparisons
308 float t_sxy, t_syx, t_sxny, t_synx;
309 float t_exy, t_eyx, t_exny, t_eynx;
310
312 float start_x, start_y, end_x, end_y;
313
314 bool d1, d2, d3, d4;
315
316 d1 = d2 = d3 = d4 = true;
317
318 bool circle = false;
319
320 if(sweep < 0)
321 {
323 sweep = -sweep;
324 }
325
328
333
334 // Check if start and endpoint are very near
335 if((end_x - start_x) * (end_x - start_x)
336 + (end_y - start_y) * (end_y - start_y)
337 < 2.0f)
338 {
339 if(sweep > 180)
340 circle = true;
341 else
342 // Nothing to draw
343 return;
344 }
345
346 t_x = -radius;
347 t_y = 0;
348 err = 2 - 2 * radius;
349
350 do
351 {
352 if(!circle)
353 {
354 t_sxy = start_x * t_y;
355 t_syx = start_y * t_x;
356 t_sxny = start_x * -t_y;
357 t_synx = start_y * -t_x;
358 t_exy = end_x * t_y;
359 t_eyx = end_y * t_x;
360 t_exny = end_x * -t_y;
361 t_eynx = end_y * -t_x;
362
363 if(sweep > 180)
364 {
365 d1 = (t_sxy - t_synx < 0 || t_exy - t_eynx > 0);
366 d2 = (t_sxy - t_syx < 0 || t_exy - t_eyx > 0);
367 d3 = (t_sxny - t_syx < 0 || t_exny - t_eyx > 0);
368 d4 = (t_sxny - t_synx < 0 || t_exny - t_eynx > 0);
369 }
370 else
371 {
372 d1 = (t_sxy - t_synx < 0 && t_exy - t_eynx > 0);
373 d2 = (t_sxy - t_syx < 0 && t_exy - t_eyx > 0);
374 d3 = (t_sxny - t_syx < 0 && t_exny - t_eyx > 0);
375 d4 = (t_sxny - t_synx < 0 && t_exny - t_eynx > 0);
376 }
377 }
378
379 if(d1)
380 ((ChildType*)(this))
381 ->ChildType::DrawPixel(x - t_x, y + t_y, on);
382 if(d2)
383 ((ChildType*)(this))
384 ->ChildType::DrawPixel(x + t_x, y + t_y, on);
385 if(d3)
386 ((ChildType*)(this))
387 ->ChildType::DrawPixel(x + t_x, y - t_y, on);
388 if(d4)
389 ((ChildType*)(this))
390 ->ChildType::DrawPixel(x - t_x, y - t_y, on);
391
392 e2 = err;
393 if(e2 <= t_y)
394 {
395 t_y++;
396 err = err + (t_y * 2 + 1);
397 if(-t_x == t_y && e2 <= t_x)
398 {
399 e2 = 0;
400 }
401 }
402 if(e2 > t_x)
403 {
404 t_x++;
405 err = err + (t_x * 2 + 1);
406 }
407 } while(t_x <= 0);
408 }
409
410 char WriteChar(char ch, FontDef font, bool on) override
411 {
412 uint32_t i, b, j;
413
414 // Check if character is valid
415 if(ch < 32 || ch > 126)
416 return 0;
417
418 // Check remaining space on current line
419 if(Width() < (currentX_ + font.FontWidth)
420 || Height() < (currentY_ + font.FontHeight))
421 {
422 // Not enough space on current line
423 return 0;
424 }
425
426 // Use the font to write
427 for(i = 0; i < font.FontHeight; i++)
428 {
429 b = font.data[(ch - 32) * font.FontHeight + i];
430 for(j = 0; j < font.FontWidth; j++)
431 {
432 if((b << j) & 0x8000)
433 {
434 ((ChildType*)(this))
435 ->ChildType::DrawPixel(
436 currentX_ + j, (currentY_ + i), on);
437 }
438 else
439 {
440 ((ChildType*)(this))
441 ->ChildType::DrawPixel(
442 currentX_ + j, (currentY_ + i), !on);
443 }
444 }
445 }
446
447 // The current space is now taken
448 SetCursor(currentX_ + font.FontWidth, currentY_);
449
450 // Return written char for validation
451 return ch;
452 }
453
454 char WriteString(const char* str, FontDef font, bool on) override
455 {
456 // Write until null-byte
457 while(*str)
458 {
459 if(((ChildType*)(this))->ChildType::WriteChar(*str, font, on)
460 != *str)
461 {
462 // Char could not be written
463 return *str;
464 }
465
466 // Next char
467 str++;
468 }
469
470 // Everything ok
471 return *str;
472 }
473
475 const FontDef& font,
478 bool on) override
479 {
480 const auto alignedRect
481 = GetTextRect(str, font).AlignedWithin(boundingBox, alignment);
482 SetCursor(alignedRect.GetX(), alignedRect.GetY());
483 ((ChildType*)(this))->ChildType::WriteString(str, font, on);
484 return alignedRect;
485 }
486
487 private:
488 uint32_t strlen(const char* string)
489 {
490 uint32_t result = 0;
491 while(*string++ != '\0')
492 result++;
493 return result;
494 }
495
496 Rectangle GetTextRect(const char* text, const FontDef& font)
497 {
498 const auto numChars = strlen(text);
499 return {int16_t(numChars * font.FontWidth), font.FontHeight};
500 }
501};
502
503} // namespace daisy
Definition color_display.h:18
virtual Rectangle WriteStringAligned(const char *str, const FontDef &font, Rectangle boundingBox, Alignment alignment, bool on)=0
virtual void DrawPixel(uint_fast8_t x, uint_fast8_t y, bool on)=0
Rectangle GetBounds() const
Definition color_display.h:26
virtual uint16_t Width() const =0
uint16_t currentY_
Definition color_display.h:199
virtual char WriteChar(char ch, FontDef font, bool on)=0
virtual char WriteString(const char *str, FontDef font, bool on)=0
void DrawCircle(uint_fast8_t x, uint_fast8_t y, uint_fast8_t radius, bool on)
Definition color_display.h:138
size_t CurrentY()
Definition color_display.h:33
virtual uint16_t Height() const =0
size_t CurrentX()
Definition color_display.h:32
virtual void DrawLine(uint_fast8_t x1, uint_fast8_t y1, uint_fast8_t x2, uint_fast8_t y2, bool on)=0
virtual void SetColorBG(uint8_t red, uint8_t green, uint8_t blue)=0
ColorGraphicsDisplay()
Definition color_display.h:20
void SetCursor(uint16_t x, uint16_t y)
Definition color_display.h:185
virtual ~ColorGraphicsDisplay()
Definition color_display.h:21
virtual void Fill(bool on)=0
uint16_t currentX_
Definition color_display.h:198
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
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
virtual void SetColorFG(uint8_t red, uint8_t green, uint8_t blue)=0
void DrawRect(const Rectangle &rect, bool on, bool fill=false)
Definition color_display.h:103
Definition color_display.h:230
char WriteString(const char *str, FontDef font, bool on) override
Definition color_display.h:454
void DrawLine(uint_fast8_t x1, uint_fast8_t y1, uint_fast8_t x2, uint_fast8_t y2, bool on) override
Definition color_display.h:235
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 color_display.h:271
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 color_display.h:297
Rectangle WriteStringAligned(const char *str, const FontDef &font, Rectangle boundingBox, Alignment alignment, bool on) override
Definition color_display.h:474
ColorGraphicsDisplayImpl()
Definition color_display.h:232
char WriteChar(char ch, FontDef font, bool on) override
Definition color_display.h:410
virtual ~ColorGraphicsDisplayImpl()
Definition color_display.h:233
Definition leddriver.h:33
Definition graphics_common.h:22
Rectangle AlignedWithin(const Rectangle &other, Alignment alignment) const
Definition graphics_common.h:209
#define deg2rad(deg)
Definition color_display.h:8
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