tempcommit 13/05

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