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_Indexed.cpp (5149B)

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