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)