Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Thu Jul 14 2022 13:24:40 by
1.7.2