Merge pull request #749 from 0x0aa/optimize-ssd1306-draw-vline
optimize ssd1306_draw_vline
This commit is contained in:
		
						commit
						76f3181891
					
				
					 1 changed files with 15 additions and 64 deletions
				
			
		| 
						 | 
					@ -588,7 +588,7 @@ int ssd1306_draw_hline(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, ui
 | 
				
			||||||
int ssd1306_draw_vline(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, uint8_t h, ssd1306_color_t color)
 | 
					int ssd1306_draw_vline(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, uint8_t h, ssd1306_color_t color)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint16_t index;
 | 
					    uint16_t index;
 | 
				
			||||||
    uint8_t mask, mod, t;
 | 
					    uint8_t fill, mask, mod;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // boundary check
 | 
					    // boundary check
 | 
				
			||||||
    if ((x >= dev->width) || (x < 0) || (y >= dev->height) || (y < 0))
 | 
					    if ((x >= dev->width) || (x < 0) || (y >= dev->height) || (y < 0))
 | 
				
			||||||
| 
						 | 
					@ -598,17 +598,15 @@ int ssd1306_draw_vline(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, ui
 | 
				
			||||||
    if (y + h > dev->height)
 | 
					    if (y + h > dev->height)
 | 
				
			||||||
        h = dev->height - y;
 | 
					        h = dev->height - y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    t = h;
 | 
					    do {
 | 
				
			||||||
    index = x + (y / 8) * dev->width;
 | 
					        mod = y & 7;
 | 
				
			||||||
    mod = y & 7;
 | 
					        fill = 8 - mod;
 | 
				
			||||||
    if (mod) // partial line that does not fit into byte at top
 | 
					
 | 
				
			||||||
    {
 | 
					        if (fill > h)
 | 
				
			||||||
        // Magic from Adafruit
 | 
					            fill = h;
 | 
				
			||||||
        mod = 8 - mod;
 | 
					
 | 
				
			||||||
        static const uint8_t premask[8] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
 | 
					        index = x + (y / 8) * dev->width;
 | 
				
			||||||
        mask = premask[mod];
 | 
					        mask = ((1 << fill) - 1) << mod;
 | 
				
			||||||
        if (t < mod)
 | 
					 | 
				
			||||||
            mask &= (0xFF >> (mod - t));
 | 
					 | 
				
			||||||
        switch (color) {
 | 
					        switch (color) {
 | 
				
			||||||
            case OLED_COLOR_WHITE:
 | 
					            case OLED_COLOR_WHITE:
 | 
				
			||||||
                fb[index] |= mask;
 | 
					                fb[index] |= mask;
 | 
				
			||||||
| 
						 | 
					@ -623,58 +621,11 @@ int ssd1306_draw_vline(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, ui
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (t < mod)
 | 
					        y += fill;
 | 
				
			||||||
            return 0;
 | 
					        h -= fill;
 | 
				
			||||||
        t -= mod;
 | 
					
 | 
				
			||||||
        index += dev->width;
 | 
					    } while(h > 0);
 | 
				
			||||||
    }
 | 
					
 | 
				
			||||||
    if (t >= 8) // byte aligned line at middle
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
        switch (color) {
 | 
					 | 
				
			||||||
            case OLED_COLOR_WHITE:
 | 
					 | 
				
			||||||
                do {
 | 
					 | 
				
			||||||
                    fb[index] = 0xff;
 | 
					 | 
				
			||||||
                    index += dev->width;
 | 
					 | 
				
			||||||
                    t -= 8;
 | 
					 | 
				
			||||||
                } while (t >= 8);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case OLED_COLOR_BLACK:
 | 
					 | 
				
			||||||
                do {
 | 
					 | 
				
			||||||
                    fb[index] = 0x00;
 | 
					 | 
				
			||||||
                    index += dev->width;
 | 
					 | 
				
			||||||
                    t -= 8;
 | 
					 | 
				
			||||||
                } while (t >= 8);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case OLED_COLOR_INVERT:
 | 
					 | 
				
			||||||
                do {
 | 
					 | 
				
			||||||
                    fb[index] = ~fb[index];
 | 
					 | 
				
			||||||
                    index += dev->width;
 | 
					 | 
				
			||||||
                    t -= 8;
 | 
					 | 
				
			||||||
                } while (t >= 8);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            default:
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (t) // partial line at bottom
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        mod = t & 7;
 | 
					 | 
				
			||||||
        static const uint8_t postmask[8] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
 | 
					 | 
				
			||||||
        mask = postmask[mod];
 | 
					 | 
				
			||||||
        switch (color) {
 | 
					 | 
				
			||||||
            case OLED_COLOR_WHITE:
 | 
					 | 
				
			||||||
                fb[index] |= mask;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case OLED_COLOR_BLACK:
 | 
					 | 
				
			||||||
                fb[index] &= ~mask;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case OLED_COLOR_INVERT:
 | 
					 | 
				
			||||||
                fb[index] ^= mask;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            default:
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue