E_paper, E_ink, Screen size 1.54", resolution 200x200, 4 wire spi, Waveshare, Black and White, Kl25Z, 8 wire print connector, supply 3.3 Volt, IL0373 Controller, font size is 8, 12, 16 and 24.
Diff: epdpaint.cpp
- Revision:
- 1:d27a7e06c233
- Parent:
- 0:665e04c85d8d
- Child:
- 3:e4399b5ceb4b
--- a/epdpaint.cpp Sun Mar 25 12:14:55 2018 +0000 +++ b/epdpaint.cpp Mon Mar 26 17:20:56 2018 +0000 @@ -1,343 +1,342 @@ -/** - * @filename : epdpaint.cpp - * @brief : Paint tools - * @author : Yehui from Waveshare - * - * Copyright (C) Waveshare September 9 2017 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documnetation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include <avr/pgmspace.h> -#include "epdpaint.h" - -Paint::Paint(unsigned char* image, int width, int height) { - this->rotate = ROTATE_0; - this->image = image; - /* 1 byte = 8 pixels, so the width should be the multiple of 8 */ - this->width = width % 8 ? width + 8 - (width % 8) : width; - this->height = height; -} - -Paint::~Paint() { -} - -/** - * @brief: clear the image - */ -void Paint::Clear(int colored) { - for (int x = 0; x < this->width; x++) { - for (int y = 0; y < this->height; y++) { - DrawAbsolutePixel(x, y, colored); - } - } -} - -/** - * @brief: this draws a pixel by absolute coordinates. - * this function won't be affected by the rotate parameter. - */ -void Paint::DrawAbsolutePixel(int x, int y, int colored) { - if (x < 0 || x >= this->width || y < 0 || y >= this->height) { - return; - } - if (IF_INVERT_COLOR) { - if (colored) { - image[(x + y * this->width) / 8] |= 0x80 >> (x % 8); - } else { - image[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8)); - } - } else { - if (colored) { - image[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8)); - } else { - image[(x + y * this->width) / 8] |= 0x80 >> (x % 8); - } - } -} - -/** - * @brief: Getters and Setters - */ -unsigned char* Paint::GetImage(void) { - return this->image; -} - -int Paint::GetWidth(void) { - return this->width; -} - -void Paint::SetWidth(int width) { - this->width = width % 8 ? width + 8 - (width % 8) : width; -} - -int Paint::GetHeight(void) { - return this->height; -} - -void Paint::SetHeight(int height) { - this->height = height; -} - -int Paint::GetRotate(void) { - return this->rotate; -} - -void Paint::SetRotate(int rotate){ - this->rotate = rotate; -} - -/** - * @brief: this draws a pixel by the coordinates - */ -void Paint::DrawPixel(int x, int y, int colored) { - int point_temp; - if (this->rotate == ROTATE_0) { - if(x < 0 || x >= this->width || y < 0 || y >= this->height) { - return; - } - DrawAbsolutePixel(x, y, colored); - } else if (this->rotate == ROTATE_90) { - if(x < 0 || x >= this->height || y < 0 || y >= this->width) { - return; - } - point_temp = x; - x = this->width - y; - y = point_temp; - DrawAbsolutePixel(x, y, colored); - } else if (this->rotate == ROTATE_180) { - if(x < 0 || x >= this->width || y < 0 || y >= this->height) { - return; - } - x = this->width - x; - y = this->height - y; - DrawAbsolutePixel(x, y, colored); - } else if (this->rotate == ROTATE_270) { - if(x < 0 || x >= this->height || y < 0 || y >= this->width) { - return; - } - point_temp = x; - x = y; - y = this->height - point_temp; - DrawAbsolutePixel(x, y, colored); - } -} - -/** - * @brief: this draws a charactor on the frame buffer but not refresh - */ -void Paint::DrawCharAt(int x, int y, char ascii_char, sFONT* font, int colored) { - int i, j; - unsigned int char_offset = (ascii_char - ' ') * font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0)); - const unsigned char* ptr = &font->table[char_offset]; - - for (j = 0; j < font->Height; j++) { - for (i = 0; i < font->Width; i++) { - if (pgm_read_byte(ptr) & (0x80 >> (i % 8))) { - DrawPixel(x + i, y + j, colored); - } - if (i % 8 == 7) { - ptr++; - } - } - if (font->Width % 8 != 0) { - ptr++; - } - } -} - -/** -* @brief: this displays a string on the frame buffer but not refresh -*/ -void Paint::DrawStringAt(int x, int y, const char* text, sFONT* font, int colored) { - const char* p_text = text; - unsigned int counter = 0; - int refcolumn = x; - - /* Send the string character by character on EPD */ - while (*p_text != 0) { - /* Display one character on EPD */ - DrawCharAt(refcolumn, y, *p_text, font, colored); - /* Decrement the column position by 16 */ - refcolumn += font->Width; - /* Point on the next character */ - p_text++; - counter++; - } -} - -/** -* @brief: this draws a line on the frame buffer -*/ -void Paint::DrawLine(int x0, int y0, int x1, int y1, int colored) { - /* Bresenham algorithm */ - int dx = x1 - x0 >= 0 ? x1 - x0 : x0 - x1; - int sx = x0 < x1 ? 1 : -1; - int dy = y1 - y0 <= 0 ? y1 - y0 : y0 - y1; - int sy = y0 < y1 ? 1 : -1; - int err = dx + dy; - - while((x0 != x1) && (y0 != y1)) { - DrawPixel(x0, y0 , colored); - if (2 * err >= dy) { - err += dy; - x0 += sx; - } - if (2 * err <= dx) { - err += dx; - y0 += sy; - } - } -} - -/** -* @brief: this draws a horizontal line on the frame buffer -*/ -void Paint::DrawHorizontalLine(int x, int y, int line_width, int colored) { - int i; - for (i = x; i < x + line_width; i++) { - DrawPixel(i, y, colored); - } -} - -/** -* @brief: this draws a vertical line on the frame buffer -*/ -void Paint::DrawVerticalLine(int x, int y, int line_height, int colored) { - int i; - for (i = y; i < y + line_height; i++) { - DrawPixel(x, i, colored); - } -} - -/** -* @brief: this draws a rectangle -*/ -void Paint::DrawRectangle(int x0, int y0, int x1, int y1, int colored) { - int min_x, min_y, max_x, max_y; - min_x = x1 > x0 ? x0 : x1; - max_x = x1 > x0 ? x1 : x0; - min_y = y1 > y0 ? y0 : y1; - max_y = y1 > y0 ? y1 : y0; - - DrawHorizontalLine(min_x, min_y, max_x - min_x + 1, colored); - DrawHorizontalLine(min_x, max_y, max_x - min_x + 1, colored); - DrawVerticalLine(min_x, min_y, max_y - min_y + 1, colored); - DrawVerticalLine(max_x, min_y, max_y - min_y + 1, colored); -} - -/** -* @brief: this draws a filled rectangle -*/ -void Paint::DrawFilledRectangle(int x0, int y0, int x1, int y1, int colored) { - int min_x, min_y, max_x, max_y; - int i; - min_x = x1 > x0 ? x0 : x1; - max_x = x1 > x0 ? x1 : x0; - min_y = y1 > y0 ? y0 : y1; - max_y = y1 > y0 ? y1 : y0; - - for (i = min_x; i <= max_x; i++) { - DrawVerticalLine(i, min_y, max_y - min_y + 1, colored); - } -} - -/** -* @brief: this draws a circle -*/ -void Paint::DrawCircle(int x, int y, int radius, int colored) { - /* Bresenham algorithm */ - int x_pos = -radius; - int y_pos = 0; - int err = 2 - 2 * radius; - int e2; - - do { - DrawPixel(x - x_pos, y + y_pos, colored); - DrawPixel(x + x_pos, y + y_pos, colored); - DrawPixel(x + x_pos, y - y_pos, colored); - DrawPixel(x - x_pos, y - y_pos, colored); - e2 = err; - if (e2 <= y_pos) { - err += ++y_pos * 2 + 1; - if(-x_pos == y_pos && e2 <= x_pos) { - e2 = 0; - } - } - if (e2 > x_pos) { - err += ++x_pos * 2 + 1; - } - } while (x_pos <= 0); -} - -/** -* @brief: this draws a filled circle -*/ -void Paint::DrawFilledCircle(int x, int y, int radius, int colored) { - /* Bresenham algorithm */ - int x_pos = -radius; - int y_pos = 0; - int err = 2 - 2 * radius; - int e2; - - do { - DrawPixel(x - x_pos, y + y_pos, colored); - DrawPixel(x + x_pos, y + y_pos, colored); - DrawPixel(x + x_pos, y - y_pos, colored); - DrawPixel(x - x_pos, y - y_pos, colored); - DrawHorizontalLine(x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored); - DrawHorizontalLine(x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored); - e2 = err; - if (e2 <= y_pos) { - err += ++y_pos * 2 + 1; - if(-x_pos == y_pos && e2 <= x_pos) { - e2 = 0; - } - } - if(e2 > x_pos) { - err += ++x_pos * 2 + 1; - } - } while(x_pos <= 0); -} - -/* END OF FILE */ - - - - - - - - - - - - - - - - - - - - - - - +/** + * @filename : epdpaint.cpp + * @brief : Paint tools + * @author : Yehui from Waveshare + * + * Copyright (C) Waveshare September 9 2017 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documnetation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "epdpaint.h" + +Paint::Paint(unsigned char* image, int width, int height) { + this->rotate = ROTATE_0; + this->image = image; + /* 1 byte = 8 pixels, so the width should be the multiple of 8 */ + this->width = width % 8 ? width + 8 - (width % 8) : width; + this->height = height; +} + +Paint::~Paint() { +} + +/** + * @brief: clear the image + */ +void Paint::Clear(int colored) { + for (int x = 0; x < this->width; x++) { + for (int y = 0; y < this->height; y++) { + DrawAbsolutePixel(x, y, colored); + } + } +} + +/** + * @brief: this draws a pixel by absolute coordinates. + * this function won't be affected by the rotate parameter. + */ +void Paint::DrawAbsolutePixel(int x, int y, int colored) { + if (x < 0 || x >= this->width || y < 0 || y >= this->height) { + return; + } + if (IF_INVERT_COLOR) { + if (colored) { + image[(x + y * this->width) / 8] |= 0x80 >> (x % 8); + } else { + image[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8)); + } + } else { + if (colored) { + image[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8)); + } else { + image[(x + y * this->width) / 8] |= 0x80 >> (x % 8); + } + } +} + +/** + * @brief: Getters and Setters + */ +unsigned char* Paint::GetImage(void) { + return this->image; +} + +int Paint::GetWidth(void) { + return this->width; +} + +void Paint::SetWidth(int width) { + this->width = width % 8 ? width + 8 - (width % 8) : width; +} + +int Paint::GetHeight(void) { + return this->height; +} + +void Paint::SetHeight(int height) { + this->height = height; +} + +int Paint::GetRotate(void) { + return this->rotate; +} + +void Paint::SetRotate(int rotate){ + this->rotate = rotate; +} + +/** + * @brief: this draws a pixel by the coordinates + */ +void Paint::DrawPixel(int x, int y, int colored) { + int point_temp; + if (this->rotate == ROTATE_0) { + if(x < 0 || x >= this->width || y < 0 || y >= this->height) { + return; + } + DrawAbsolutePixel(x, y, colored); + } else if (this->rotate == ROTATE_90) { + if(x < 0 || x >= this->height || y < 0 || y >= this->width) { + return; + } + point_temp = x; + x = this->width - y; + y = point_temp; + DrawAbsolutePixel(x, y, colored); + } else if (this->rotate == ROTATE_180) { + if(x < 0 || x >= this->width || y < 0 || y >= this->height) { + return; + } + x = this->width - x; + y = this->height - y; + DrawAbsolutePixel(x, y, colored); + } else if (this->rotate == ROTATE_270) { + if(x < 0 || x >= this->height || y < 0 || y >= this->width) { + return; + } + point_temp = x; + x = y; + y = this->height - point_temp; + DrawAbsolutePixel(x, y, colored); + } +} + +/** + * @brief: this draws a charactor on the frame buffer but not refresh + */ +void Paint::DrawCharAt(int x, int y, char ascii_char, sFONT* font, int colored) { + int i, j; + unsigned int char_offset = (ascii_char - ' ') * font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0)); + const unsigned char* ptr = &font->table[char_offset]; + + for (j = 0; j < font->Height; j++) { + for (i = 0; i < font->Width; i++) { + if (pgm_read_byte(ptr) & (0x80 >> (i % 8))) { + DrawPixel(x + i, y + j, colored); + } + if (i % 8 == 7) { + ptr++; + } + } + if (font->Width % 8 != 0) { + ptr++; + } + } +} +/** +* @brief: this displays a string on the frame buffer but not refresh +*/ +void Paint::DrawStringAt(int x, int y, const char* text, sFONT* font, int colored) { + const char* p_text = text; + unsigned int counter = 0; + int refcolumn = x; + + /* Send the string character by character on EPD */ + while (*p_text != 0) { + /* Display one character on EPD */ + DrawCharAt(refcolumn, y, *p_text, font, colored); + /* Decrement the column position by 16 */ + refcolumn += font->Width; + /* Point on the next character */ + p_text++; + counter++; + } +} + +/** +* @brief: this draws a line on the frame buffer +*/ +void Paint::DrawLine(int x0, int y0, int x1, int y1, int colored) { + /* Bresenham algorithm */ + int dx = x1 - x0 >= 0 ? x1 - x0 : x0 - x1; + int sx = x0 < x1 ? 1 : -1; + int dy = y1 - y0 <= 0 ? y1 - y0 : y0 - y1; + int sy = y0 < y1 ? 1 : -1; + int err = dx + dy; + + while((x0 != x1) && (y0 != y1)) { + DrawPixel(x0, y0 , colored); + if (2 * err >= dy) { + err += dy; + x0 += sx; + } + if (2 * err <= dx) { + err += dx; + y0 += sy; + } + } +} + +/** +* @brief: this draws a horizontal line on the frame buffer +*/ +void Paint::DrawHorizontalLine(int x, int y, int line_width, int colored) { + int i; + for (i = x; i < x + line_width; i++) { + DrawPixel(i, y, colored); + } +} + +/** +* @brief: this draws a vertical line on the frame buffer +*/ +void Paint::DrawVerticalLine(int x, int y, int line_height, int colored) { + int i; + for (i = y; i < y + line_height; i++) { + DrawPixel(x, i, colored); + } +} + +/** +* @brief: this draws a rectangle +*/ +void Paint::DrawRectangle(int x0, int y0, int x1, int y1, int colored) { + int min_x, min_y, max_x, max_y; + min_x = x1 > x0 ? x0 : x1; + max_x = x1 > x0 ? x1 : x0; + min_y = y1 > y0 ? y0 : y1; + max_y = y1 > y0 ? y1 : y0; + + DrawHorizontalLine(min_x, min_y, max_x - min_x + 1, colored); + DrawHorizontalLine(min_x, max_y, max_x - min_x + 1, colored); + DrawVerticalLine(min_x, min_y, max_y - min_y + 1, colored); + DrawVerticalLine(max_x, min_y, max_y - min_y + 1, colored); +} + +/** +* @brief: this draws a filled rectangle +*/ +void Paint::DrawFilledRectangle(int x0, int y0, int x1, int y1, int colored) { + int min_x, min_y, max_x, max_y; + int i; + min_x = x1 > x0 ? x0 : x1; + max_x = x1 > x0 ? x1 : x0; + min_y = y1 > y0 ? y0 : y1; + max_y = y1 > y0 ? y1 : y0; + + for (i = min_x; i <= max_x; i++) { + DrawVerticalLine(i, min_y, max_y - min_y + 1, colored); + } +} + +/** +* @brief: this draws a circle +*/ +void Paint::DrawCircle(int x, int y, int radius, int colored) { + /* Bresenham algorithm */ + int x_pos = -radius; + int y_pos = 0; + int err = 2 - 2 * radius; + int e2; + + do { + DrawPixel(x - x_pos, y + y_pos, colored); + DrawPixel(x + x_pos, y + y_pos, colored); + DrawPixel(x + x_pos, y - y_pos, colored); + DrawPixel(x - x_pos, y - y_pos, colored); + e2 = err; + if (e2 <= y_pos) { + err += ++y_pos * 2 + 1; + if(-x_pos == y_pos && e2 <= x_pos) { + e2 = 0; + } + } + if (e2 > x_pos) { + err += ++x_pos * 2 + 1; + } + } while (x_pos <= 0); +} + +/** +* @brief: this draws a filled circle +*/ +void Paint::DrawFilledCircle(int x, int y, int radius, int colored) { + /* Bresenham algorithm */ + int x_pos = -radius; + int y_pos = 0; + int err = 2 - 2 * radius; + int e2; + + do { + DrawPixel(x - x_pos, y + y_pos, colored); + DrawPixel(x + x_pos, y + y_pos, colored); + DrawPixel(x + x_pos, y - y_pos, colored); + DrawPixel(x - x_pos, y - y_pos, colored); + DrawHorizontalLine(x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored); + DrawHorizontalLine(x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored); + e2 = err; + if (e2 <= y_pos) { + err += ++y_pos * 2 + 1; + if(-x_pos == y_pos && e2 <= x_pos) { + e2 = 0; + } + } + if(e2 > x_pos) { + err += ++x_pos * 2 + 1; + } + } while(x_pos <= 0); +} + +/* END OF FILE */ + + + + + + + + + + + + + + + + + + + + + + + +