Gerrit Pathuis / Mbed 2 deprecated Epaper_epd1in54_Waveshare

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers epdpaint.cpp Source File

epdpaint.cpp

00001 /**
00002  *  @filename   :   epdpaint.cpp
00003  *  @brief      :   Paint tools
00004  *  @author     :   Yehui from Waveshare
00005  *  
00006  *  Copyright (C) Waveshare     September 9 2017
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a copy
00009  * of this software and associated documnetation files (the "Software"), to deal
00010  * in the Software without restriction, including without limitation the rights
00011  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00012  * copies of the Software, and to permit persons to  whom the Software is
00013  * furished to do so, subject to the following conditions:
00014  *
00015  * The above copyright notice and this permission notice shall be included in
00016  * all copies or substantial portions of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00019  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020  * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00021  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00022  * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00023  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00024  * THE SOFTWARE.
00025  */
00026 
00027 #include "epdpaint.h"
00028 
00029 Paint::Paint(unsigned char* image, int width, int height) {
00030     this->rotate = ROTATE_0;
00031     this->image = image;
00032     /* 1 byte = 8 pixels, so the width should be the multiple of 8 */
00033     this->width = width % 8 ? width + 8 - (width % 8) : width;
00034     this->height = height;
00035 }
00036 
00037 Paint::~Paint() {
00038 }
00039 
00040 /**
00041  *  @brief: clear the image
00042  */
00043 void Paint::Clear(int colored) {
00044     for (int x = 0; x < this->width; x++) {
00045         for (int y = 0; y < this->height; y++) {
00046             DrawAbsolutePixel(x, y, colored);
00047         }
00048     }
00049 }
00050 
00051 /**
00052  *  @brief: this draws a pixel by absolute coordinates.
00053  *          this function won't be affected by the rotate parameter.
00054  */
00055 void Paint::DrawAbsolutePixel(int x, int y, int colored) {
00056     if (x < 0 || x >= this->width || y < 0 || y >= this->height) {
00057         return;
00058     }
00059     if (IF_INVERT_COLOR) {
00060         if (colored) {
00061             image[(x + y * this->width) / 8] |= 0x80 >> (x % 8);
00062         } else {
00063             image[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8));
00064         }
00065     } else {
00066         if (colored) {
00067             image[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8));
00068         } else {
00069             image[(x + y * this->width) / 8] |= 0x80 >> (x % 8);
00070         }
00071     }
00072 }
00073 
00074 /**
00075  *  @brief: Getters and Setters
00076  */
00077 unsigned char* Paint::GetImage(void) {
00078     return this->image;
00079 }
00080 
00081 int Paint::GetWidth(void) {
00082     return this->width;
00083 }
00084 
00085 void Paint::SetWidth(int width) {
00086     this->width = width % 8 ? width + 8 - (width % 8) : width;
00087 }
00088 
00089 int Paint::GetHeight(void) {
00090     return this->height;
00091 }
00092 
00093 void Paint::SetHeight(int height) {
00094     this->height = height;
00095 }
00096 
00097 int Paint::GetRotate(void) {
00098     return this->rotate;
00099 }
00100 
00101 void Paint::SetRotate(int rotate){
00102     this->rotate = rotate;
00103 }
00104 
00105 /**
00106  *  @brief: this draws a pixel by the coordinates
00107  */
00108 void Paint::DrawPixel(int x, int y, int colored) {
00109     int point_temp;
00110     if (this->rotate == ROTATE_0) {
00111         if(x < 0 || x >= this->width || y < 0 || y >= this->height) {
00112             return;
00113         }
00114         DrawAbsolutePixel(x, y, colored);
00115     } else if (this->rotate == ROTATE_90) {
00116         if(x < 0 || x >= this->height || y < 0 || y >= this->width) {
00117           return;
00118         }
00119         point_temp = x;
00120         x = this->width - y;
00121         y = point_temp;
00122         DrawAbsolutePixel(x, y, colored);
00123     } else if (this->rotate == ROTATE_180) {
00124         if(x < 0 || x >= this->width || y < 0 || y >= this->height) {
00125           return;
00126         }
00127         x = this->width - x;
00128         y = this->height - y;
00129         DrawAbsolutePixel(x, y, colored);
00130     } else if (this->rotate == ROTATE_270) {
00131         if(x < 0 || x >= this->height || y < 0 || y >= this->width) {
00132           return;
00133         }
00134         point_temp = x;
00135         x = y;
00136         y = this->height - point_temp;
00137         DrawAbsolutePixel(x, y, colored);
00138     }
00139 }
00140 
00141 /**
00142  *  @brief: this draws a charactor on the frame buffer but not refresh
00143  */
00144 void Paint::DrawCharAt(int x, int y, char ascii_char, sFONT* font, int colored) {
00145     int i, j;
00146     unsigned int char_offset = (ascii_char - ' ') * font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0));
00147     const unsigned char* ptr = &font->table[char_offset];
00148 
00149     for (j = 0; j < font->Height; j++) {
00150         for (i = 0; i < font->Width; i++) {
00151             //if (pgm_read_byte(ptr) & (0x80 >> (i % 8))) {
00152                 if (*(ptr) & (0x80 >> (i % 8))) {
00153                 DrawPixel(x + i, y + j, colored);
00154             }
00155             if (i % 8 == 7) {
00156                 ptr++;
00157             }
00158         }
00159         if (font->Width % 8 != 0) {
00160             ptr++;
00161         }
00162     }
00163 }
00164 
00165 /**
00166 *  @brief: this displays a string on the frame buffer but not refresh
00167 */
00168 void Paint::DrawStringAt(int x, int y, const char* text, sFONT* font, int colored) {
00169     const char* p_text = text;
00170     unsigned int counter = 0;
00171     int refcolumn = x;
00172     
00173     /* Send the string character by character on EPD */
00174     while (*p_text != 0) {
00175         /* Display one character on EPD */
00176         DrawCharAt(refcolumn, y, *p_text, font, colored);
00177         /* Decrement the column position by 16 */
00178         refcolumn += font->Width;
00179         /* Point on the next character */
00180         p_text++;
00181         counter++;
00182     }
00183 }
00184 
00185 /**
00186 *  @brief: this draws a line on the frame buffer
00187 */
00188 void Paint::DrawLine(int x0, int y0, int x1, int y1, int colored) {
00189     /* Bresenham algorithm */
00190     int dx = x1 - x0 >= 0 ? x1 - x0 : x0 - x1;
00191     int sx = x0 < x1 ? 1 : -1;
00192     int dy = y1 - y0 <= 0 ? y1 - y0 : y0 - y1;
00193     int sy = y0 < y1 ? 1 : -1;
00194     int err = dx + dy;
00195 
00196     while((x0 != x1) && (y0 != y1)) {
00197         DrawPixel(x0, y0 , colored);
00198         if (2 * err >= dy) {     
00199             err += dy;
00200             x0 += sx;
00201         }
00202         if (2 * err <= dx) {
00203             err += dx; 
00204             y0 += sy;
00205         }
00206     }
00207 }
00208 
00209 /**
00210 *  @brief: this draws a horizontal line on the frame buffer
00211 */
00212 void Paint::DrawHorizontalLine(int x, int y, int line_width, int colored) {
00213     int i;
00214     for (i = x; i < x + line_width; i++) {
00215         DrawPixel(i, y, colored);
00216     }
00217 }
00218 
00219 /**
00220 *  @brief: this draws a vertical line on the frame buffer
00221 */
00222 void Paint::DrawVerticalLine(int x, int y, int line_height, int colored) {
00223     int i;
00224     for (i = y; i < y + line_height; i++) {
00225         DrawPixel(x, i, colored);
00226     }
00227 }
00228 
00229 /**
00230 *  @brief: this draws a rectangle
00231 */
00232 void Paint::DrawRectangle(int x0, int y0, int x1, int y1, int colored) {
00233     int min_x, min_y, max_x, max_y;
00234     min_x = x1 > x0 ? x0 : x1;
00235     max_x = x1 > x0 ? x1 : x0;
00236     min_y = y1 > y0 ? y0 : y1;
00237     max_y = y1 > y0 ? y1 : y0;
00238     
00239     DrawHorizontalLine(min_x, min_y, max_x - min_x + 1, colored);
00240     DrawHorizontalLine(min_x, max_y, max_x - min_x + 1, colored);
00241     DrawVerticalLine(min_x, min_y, max_y - min_y + 1, colored);
00242     DrawVerticalLine(max_x, min_y, max_y - min_y + 1, colored);
00243 }
00244 
00245 /**
00246 *  @brief: this draws a filled rectangle
00247 */
00248 void Paint::DrawFilledRectangle(int x0, int y0, int x1, int y1, int colored) {
00249     int min_x, min_y, max_x, max_y;
00250     int i;
00251     min_x = x1 > x0 ? x0 : x1;
00252     max_x = x1 > x0 ? x1 : x0;
00253     min_y = y1 > y0 ? y0 : y1;
00254     max_y = y1 > y0 ? y1 : y0;
00255     
00256     for (i = min_x; i <= max_x; i++) {
00257       DrawVerticalLine(i, min_y, max_y - min_y + 1, colored);
00258     }
00259 }
00260 
00261 /**
00262 *  @brief: this draws a circle
00263 */
00264 void Paint::DrawCircle(int x, int y, int radius, int colored) {
00265     /* Bresenham algorithm */
00266     int x_pos = -radius;
00267     int y_pos = 0;
00268     int err = 2 - 2 * radius;
00269     int e2;
00270 
00271     do {
00272         DrawPixel(x - x_pos, y + y_pos, colored);
00273         DrawPixel(x + x_pos, y + y_pos, colored);
00274         DrawPixel(x + x_pos, y - y_pos, colored);
00275         DrawPixel(x - x_pos, y - y_pos, colored);
00276         e2 = err;
00277         if (e2 <= y_pos) {
00278             err += ++y_pos * 2 + 1;
00279             if(-x_pos == y_pos && e2 <= x_pos) {
00280               e2 = 0;
00281             }
00282         }
00283         if (e2 > x_pos) {
00284             err += ++x_pos * 2 + 1;
00285         }
00286     } while (x_pos <= 0);
00287 }
00288 
00289 /**
00290 *  @brief: this draws a filled circle
00291 */
00292 void Paint::DrawFilledCircle(int x, int y, int radius, int colored) {
00293     /* Bresenham algorithm */
00294     int x_pos = -radius;
00295     int y_pos = 0;
00296     int err = 2 - 2 * radius;
00297     int e2;
00298 
00299     do {
00300         DrawPixel(x - x_pos, y + y_pos, colored);
00301         DrawPixel(x + x_pos, y + y_pos, colored);
00302         DrawPixel(x + x_pos, y - y_pos, colored);
00303         DrawPixel(x - x_pos, y - y_pos, colored);
00304         DrawHorizontalLine(x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored);
00305         DrawHorizontalLine(x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored);
00306         e2 = err;
00307         if (e2 <= y_pos) {
00308             err += ++y_pos * 2 + 1;
00309             if(-x_pos == y_pos && e2 <= x_pos) {
00310                 e2 = 0;
00311             }
00312         }
00313         if(e2 > x_pos) {
00314             err += ++x_pos * 2 + 1;
00315         }
00316     } while(x_pos <= 0);
00317 }
00318 
00319 /* END OF FILE */
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343