acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

Arduino_Canvas.cpp (5242B)

      1 #include "../Arduino_DataBus.h"
      2 #if !defined(LITTLE_FOOT_PRINT)
      3 
      4 #include "../Arduino_GFX.h"
      5 #include "Arduino_Canvas.h"
      6 
      7 Arduino_Canvas::Arduino_Canvas(
      8     int16_t w, int16_t h, Arduino_G *output, int16_t output_x, int16_t output_y)
      9     : Arduino_GFX(w, h), _output(output), _output_x(output_x), _output_y(output_y)
     10 {
     11 }
     12 
     13 bool Arduino_Canvas::begin(int32_t speed)
     14 {
     15   if (
     16       (speed != GFX_SKIP_OUTPUT_BEGIN) && (_output))
     17   {
     18     if (!_output->begin(speed))
     19     {
     20       return false;
     21     }
     22   }
     23 
     24   size_t s = _width * _height * 2;
     25 #if defined(ESP32)
     26   if (psramFound())
     27   {
     28     _framebuffer = (uint16_t *)ps_malloc(s);
     29   }
     30   else
     31   {
     32     _framebuffer = (uint16_t *)malloc(s);
     33   }
     34 #else
     35   _framebuffer = (uint16_t *)malloc(s);
     36 #endif
     37   if (!_framebuffer)
     38   {
     39     return false;
     40   }
     41 
     42   return true;
     43 }
     44 
     45 void Arduino_Canvas::writePixelPreclipped(int16_t x, int16_t y, uint16_t color)
     46 {
     47   _framebuffer[((int32_t)y * _width) + x] = color;
     48 }
     49 
     50 void Arduino_Canvas::writeFastVLine(int16_t x, int16_t y,
     51                                     int16_t h, uint16_t color)
     52 {
     53   if (_ordered_in_range(x, 0, _max_x) && h)
     54   { // X on screen, nonzero height
     55     if (h < 0)
     56     {             // If negative height...
     57       y += h + 1; //   Move Y to top edge
     58       h = -h;     //   Use positive height
     59     }
     60     if (y <= _max_y)
     61     { // Not off bottom
     62       int16_t y2 = y + h - 1;
     63       if (y2 >= 0)
     64       { // Not off top
     65         // Line partly or fully overlaps screen
     66         if (y < 0)
     67         {
     68           y = 0;
     69           h = y2 + 1;
     70         } // Clip top
     71         if (y2 > _max_y)
     72         {
     73           h = _max_y - y + 1;
     74         } // Clip bottom
     75 
     76         uint16_t *fb = _framebuffer + ((int32_t)y * _width) + x;
     77         while (h--)
     78         {
     79           *fb = color;
     80           fb += _width;
     81         }
     82       }
     83     }
     84   }
     85 }
     86 
     87 void Arduino_Canvas::writeFastHLine(int16_t x, int16_t y,
     88                                     int16_t w, uint16_t color)
     89 {
     90   if (_ordered_in_range(y, 0, _max_y) && w)
     91   { // Y on screen, nonzero width
     92     if (w < 0)
     93     {             // If negative width...
     94       x += w + 1; //   Move X to left edge
     95       w = -w;     //   Use positive width
     96     }
     97     if (x <= _max_x)
     98     { // Not off right
     99       int16_t x2 = x + w - 1;
    100       if (x2 >= 0)
    101       { // Not off left
    102         // Line partly or fully overlaps screen
    103         if (x < 0)
    104         {
    105           x = 0;
    106           w = x2 + 1;
    107         } // Clip left
    108         if (x2 > _max_x)
    109         {
    110           w = _max_x - x + 1;
    111         } // Clip right
    112 
    113         uint16_t *fb = _framebuffer + ((int32_t)y * _width) + x;
    114         while (w--)
    115         {
    116           *(fb++) = color;
    117         }
    118       }
    119     }
    120   }
    121 }
    122 
    123 void Arduino_Canvas::writeFillRectPreclipped(int16_t x, int16_t y,
    124                                              int16_t w, int16_t h, uint16_t color)
    125 {
    126   uint16_t *row = _framebuffer;
    127   row += y * _width;
    128   row += x;
    129   for (int j = 0; j < h; j++)
    130   {
    131     for (int i = 0; i < w; i++)
    132     {
    133       row[i] = color;
    134     }
    135     row += _width;
    136   }
    137 }
    138 
    139 void Arduino_Canvas::draw16bitRGBBitmap(int16_t x, int16_t y,
    140                                         uint16_t *bitmap, int16_t w, int16_t h)
    141 {
    142   if (
    143       ((x + w - 1) < 0) || // Outside left
    144       ((y + h - 1) < 0) || // Outside top
    145       (x > _max_x) ||      // Outside right
    146       (y > _max_y)         // Outside bottom
    147   )
    148   {
    149     return;
    150   }
    151   else
    152   {
    153     int16_t xskip = 0;
    154     if ((y + h - 1) > _max_y)
    155     {
    156       h -= (y + h - 1) - _max_y;
    157     }
    158     if (y < 0)
    159     {
    160       bitmap -= y * w;
    161       h += y;
    162       y = 0;
    163     }
    164     if ((x + w - 1) > _max_x)
    165     {
    166       xskip = (x + w - 1) - _max_x;
    167       w -= xskip;
    168     }
    169     if (x < 0)
    170     {
    171       bitmap -= x;
    172       xskip -= x;
    173       w += x;
    174       x = 0;
    175     }
    176     uint16_t *row = _framebuffer;
    177     row += y * _width;
    178     row += x;
    179     for (int j = 0; j < h; j++)
    180     {
    181       for (int i = 0; i < w; i++)
    182       {
    183         row[i] = *bitmap++;
    184       }
    185       bitmap += xskip;
    186       row += _width;
    187     }
    188   }
    189 }
    190 
    191 void Arduino_Canvas::draw16bitBeRGBBitmap(int16_t x, int16_t y,
    192                                           uint16_t *bitmap, int16_t w, int16_t h)
    193 {
    194   if (
    195       ((x + w - 1) < 0) || // Outside left
    196       ((y + h - 1) < 0) || // Outside top
    197       (x > _max_x) ||      // Outside right
    198       (y > _max_y)         // Outside bottom
    199   )
    200   {
    201     return;
    202   }
    203   else
    204   {
    205     int16_t xskip = 0;
    206     if ((y + h - 1) > _max_y)
    207     {
    208       h -= (y + h - 1) - _max_y;
    209     }
    210     if (y < 0)
    211     {
    212       bitmap -= y * w;
    213       h += y;
    214       y = 0;
    215     }
    216     if ((x + w - 1) > _max_x)
    217     {
    218       xskip = (x + w - 1) - _max_x;
    219       w -= xskip;
    220     }
    221     if (x < 0)
    222     {
    223       bitmap -= x;
    224       xskip -= x;
    225       w += x;
    226       x = 0;
    227     }
    228     uint16_t *row = _framebuffer;
    229     row += y * _width;
    230     row += x;
    231     uint16_t color;
    232     for (int j = 0; j < h; j++)
    233     {
    234       for (int i = 0; i < w; i++)
    235       {
    236         color = *bitmap++;
    237         MSB_16_SET(row[i], color);
    238       }
    239       bitmap += xskip;
    240       row += _width;
    241     }
    242   }
    243 }
    244 
    245 void Arduino_Canvas::flush()
    246 {
    247   if (_output)
    248   {
    249     _output->draw16bitRGBBitmap(_output_x, _output_y, _framebuffer, _width, _height);
    250   }
    251 }
    252 
    253 uint16_t *Arduino_Canvas::getFramebuffer()
    254 {
    255   return _framebuffer;
    256 }
    257 
    258 #endif // !defined(LITTLE_FOOT_PRINT)