Kenji Arai / EPD_2R13

Dependents:   ePD_2R13inch_test_program

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 <avr/pgmspace.h>  by JH1PJL for mbed-os5 Apr.28,2019
00028 #include "epdpaint.h"
00029 
00030 Paint::Paint(unsigned char* image, int width, int height)
00031 {
00032     this->rotate = ROTATE_0;
00033     this->image = image;
00034     /* 1 byte = 8 pixels, so the width should be the multiple of 8 */
00035     this->width = width % 8 ? width + 8 - (width % 8) : width;
00036     this->height = height;
00037 }
00038 
00039 Paint::~Paint()
00040 {
00041 }
00042 
00043 /**
00044  *  @brief: clear the image
00045  */
00046 void Paint::Clear(int colored)
00047 {
00048     for (int x = 0; x < this->width; x++) {
00049         for (int y = 0; y < this->height; y++) {
00050             DrawAbsolutePixel(x, y, colored);
00051         }
00052     }
00053 }
00054 
00055 /**
00056  *  @brief: this draws a pixel by absolute coordinates.
00057  *          this function won't be affected by the rotate parameter.
00058  */
00059 void Paint::DrawAbsolutePixel(int x, int y, int colored)
00060 {
00061     if (x < 0 || x >= this->width || y < 0 || y >= this->height) {
00062         return;
00063     }
00064     if (IF_INVERT_COLOR) {
00065         if (colored) {
00066             image[(x + y * this->width) / 8] |= 0x80 >> (x % 8);
00067         } else {
00068             image[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8));
00069         }
00070     } else {
00071         if (colored) {
00072             image[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8));
00073         } else {
00074             image[(x + y * this->width) / 8] |= 0x80 >> (x % 8);
00075         }
00076     }
00077 }
00078 
00079 /**
00080  *  @brief: Getters and Setters
00081  */
00082 unsigned char* Paint::GetImage(void)
00083 {
00084     return this->image;
00085 }
00086 
00087 int Paint::GetWidth(void)
00088 {
00089     return this->width;
00090 }
00091 
00092 void Paint::SetWidth(int width)
00093 {
00094     this->width = width % 8 ? width + 8 - (width % 8) : width;
00095 }
00096 
00097 int Paint::GetHeight(void)
00098 {
00099     return this->height;
00100 }
00101 
00102 void Paint::SetHeight(int height)
00103 {
00104     this->height = height;
00105 }
00106 
00107 int Paint::GetRotate(void)
00108 {
00109     return this->rotate;
00110 }
00111 
00112 void Paint::SetRotate(int rotate)
00113 {
00114     this->rotate = rotate;
00115 }
00116 
00117 /**
00118  *  @brief: this draws a pixel by the coordinates
00119  */
00120 void Paint::DrawPixel(int x, int y, int colored)
00121 {
00122     int point_temp;
00123     if (this->rotate == ROTATE_0) {
00124         if(x < 0 || x >= this->width || y < 0 || y >= this->height) {
00125             return;
00126         }
00127         DrawAbsolutePixel(x, y, colored);
00128     } else if (this->rotate == ROTATE_90) {
00129         if(x < 0 || x >= this->height || y < 0 || y >= this->width) {
00130             return;
00131         }
00132         point_temp = x;
00133         x = this->width - y;
00134         y = point_temp;
00135         DrawAbsolutePixel(x, y, colored);
00136     } else if (this->rotate == ROTATE_180) {
00137         if(x < 0 || x >= this->width || y < 0 || y >= this->height) {
00138             return;
00139         }
00140         x = this->width - x;
00141         y = this->height - y;
00142         DrawAbsolutePixel(x, y, colored);
00143     } else if (this->rotate == ROTATE_270) {
00144         if(x < 0 || x >= this->height || y < 0 || y >= this->width) {
00145             return;
00146         }
00147         point_temp = x;
00148         x = y;
00149         y = this->height - point_temp;
00150         DrawAbsolutePixel(x, y, colored);
00151     }
00152 }
00153 
00154 /**
00155  *  @brief: this draws a charactor on the frame buffer but not refresh
00156  */
00157 void Paint::DrawCharAt(int x, int y, char ascii_char, sFONT* font, int colored)
00158 {
00159     int i, j;
00160     unsigned int char_offset = (ascii_char - ' ') * font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0));
00161     const unsigned char* ptr = &font->table[char_offset];
00162 
00163     for (j = 0; j < font->Height; j++) {
00164         for (i = 0; i < font->Width; i++) {
00165             if (*ptr & (0x80 >> (i % 8))) {
00166                 DrawPixel(x + i, y + j, colored);
00167             }
00168             if (i % 8 == 7) {
00169                 ptr++;
00170             }
00171         }
00172         if (font->Width % 8 != 0) {
00173             ptr++;
00174         }
00175     }
00176 }
00177 
00178 /**
00179 *  @brief: this displays a string on the frame buffer but not refresh
00180 */
00181 void Paint::DrawStringAt(int x, int y, const char* text, sFONT* font, int colored)
00182 {
00183     const char* p_text = text;
00184     unsigned int counter = 0;
00185     int refcolumn = x;
00186 
00187     /* Send the string character by character on EPD */
00188     while (*p_text != 0) {
00189         /* Display one character on EPD */
00190         DrawCharAt(refcolumn, y, *p_text, font, colored);
00191         /* Decrement the column position by 16 */
00192         refcolumn += font->Width;
00193         /* Point on the next character */
00194         p_text++;
00195         counter++;
00196     }
00197 }
00198 
00199 /**
00200 *  @brief: this draws a line on the frame buffer
00201 */
00202 void Paint::DrawLine(int x0, int y0, int x1, int y1, int colored)
00203 {
00204     /* Bresenham algorithm */
00205     int dx = x1 - x0 >= 0 ? x1 - x0 : x0 - x1;
00206     int sx = x0 < x1 ? 1 : -1;
00207     int dy = y1 - y0 <= 0 ? y1 - y0 : y0 - y1;
00208     int sy = y0 < y1 ? 1 : -1;
00209     int err = dx + dy;
00210 
00211     while((x0 != x1) && (y0 != y1)) {
00212         DrawPixel(x0, y0, colored);
00213         if (2 * err >= dy) {
00214             err += dy;
00215             x0 += sx;
00216         }
00217         if (2 * err <= dx) {
00218             err += dx;
00219             y0 += sy;
00220         }
00221     }
00222 }
00223 
00224 /**
00225 *  @brief: this draws a horizontal line on the frame buffer
00226 */
00227 void Paint::DrawHorizontalLine(int x, int y, int line_width, int colored)
00228 {
00229     int i;
00230     for (i = x; i < x + line_width; i++) {
00231         DrawPixel(i, y, colored);
00232     }
00233 }
00234 
00235 /**
00236 *  @brief: this draws a vertical line on the frame buffer
00237 */
00238 void Paint::DrawVerticalLine(int x, int y, int line_height, int colored)
00239 {
00240     int i;
00241     for (i = y; i < y + line_height; i++) {
00242         DrawPixel(x, i, colored);
00243     }
00244 }
00245 
00246 /**
00247 *  @brief: this draws a rectangle
00248 */
00249 void Paint::DrawRectangle(int x0, int y0, int x1, int y1, int colored)
00250 {
00251     int min_x, min_y, max_x, max_y;
00252     min_x = x1 > x0 ? x0 : x1;
00253     max_x = x1 > x0 ? x1 : x0;
00254     min_y = y1 > y0 ? y0 : y1;
00255     max_y = y1 > y0 ? y1 : y0;
00256 
00257     DrawHorizontalLine(min_x, min_y, max_x - min_x + 1, colored);
00258     DrawHorizontalLine(min_x, max_y, max_x - min_x + 1, colored);
00259     DrawVerticalLine(min_x, min_y, max_y - min_y + 1, colored);
00260     DrawVerticalLine(max_x, min_y, max_y - min_y + 1, colored);
00261 }
00262 
00263 /**
00264 *  @brief: this draws a filled rectangle
00265 */
00266 void Paint::DrawFilledRectangle(int x0, int y0, int x1, int y1, int colored)
00267 {
00268     int min_x, min_y, max_x, max_y;
00269     int i;
00270     min_x = x1 > x0 ? x0 : x1;
00271     max_x = x1 > x0 ? x1 : x0;
00272     min_y = y1 > y0 ? y0 : y1;
00273     max_y = y1 > y0 ? y1 : y0;
00274 
00275     for (i = min_x; i <= max_x; i++) {
00276         DrawVerticalLine(i, min_y, max_y - min_y + 1, colored);
00277     }
00278 }
00279 
00280 /**
00281 *  @brief: this draws a circle
00282 */
00283 void Paint::DrawCircle(int x, int y, int radius, int colored)
00284 {
00285     /* Bresenham algorithm */
00286     int x_pos = -radius;
00287     int y_pos = 0;
00288     int err = 2 - 2 * radius;
00289     int e2;
00290 
00291     do {
00292         DrawPixel(x - x_pos, y + y_pos, colored);
00293         DrawPixel(x + x_pos, y + y_pos, colored);
00294         DrawPixel(x + x_pos, y - y_pos, colored);
00295         DrawPixel(x - x_pos, y - y_pos, colored);
00296         e2 = err;
00297         if (e2 <= y_pos) {
00298             err += ++y_pos * 2 + 1;
00299             if(-x_pos == y_pos && e2 <= x_pos) {
00300                 e2 = 0;
00301             }
00302         }
00303         if (e2 > x_pos) {
00304             err += ++x_pos * 2 + 1;
00305         }
00306     } while (x_pos <= 0);
00307 }
00308 
00309 /**
00310 *  @brief: this draws a filled circle
00311 */
00312 void Paint::DrawFilledCircle(int x, int y, int radius, int colored)
00313 {
00314     /* Bresenham algorithm */
00315     int x_pos = -radius;
00316     int y_pos = 0;
00317     int err = 2 - 2 * radius;
00318     int e2;
00319 
00320     do {
00321         DrawPixel(x - x_pos, y + y_pos, colored);
00322         DrawPixel(x + x_pos, y + y_pos, colored);
00323         DrawPixel(x + x_pos, y - y_pos, colored);
00324         DrawPixel(x - x_pos, y - y_pos, colored);
00325         DrawHorizontalLine(x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored);
00326         DrawHorizontalLine(x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored);
00327         e2 = err;
00328         if (e2 <= y_pos) {
00329             err += ++y_pos * 2 + 1;
00330             if(-x_pos == y_pos && e2 <= x_pos) {
00331                 e2 = 0;
00332             }
00333         }
00334         if(e2 > x_pos) {
00335             err += ++x_pos * 2 + 1;
00336         }
00337     } while(x_pos <= 0);
00338 }
00339 
00340 /* END OF FILE */
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363