R_API void r_cons_canvas_line_back_edge (RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style, int ybendpoint1, int xbendpoint, int ybendpoint2, int isvert) { int min_x1 = R_MIN (x, xbendpoint); int min_x2 = R_MIN (x2, xbendpoint); int diff_x1 = R_ABS (x - xbendpoint); int diff_x2 = R_ABS (x2 - xbendpoint); int diff_y = R_ABS ((y + ybendpoint1 + 1) - (y2 - ybendpoint2- 1)); int w1 = diff_x1 == 0 ? 0 : diff_x1 + 1; int w2 = diff_x2 == 0 ? 0 : diff_x2 + 1; apply_line_style (c, x, y, x2, y2, style, isvert); if (isvert) { draw_vertical_line (c, x, y + 1, ybendpoint1 + 1); draw_horizontal_line (c, min_x1, y + ybendpoint1 + 2, w1, REV_APEX_APEX); draw_vertical_line (c, xbendpoint, y2 - ybendpoint2 + 1, diff_y - 1); draw_horizontal_line (c, min_x2, y2 - ybendpoint2, w2, DOT_DOT); draw_vertical_line (c, x2, y2 - ybendpoint2 + 1, ybendpoint2); } else { int miny1 = R_MIN (y, xbendpoint); int miny2 = R_MIN (y2, xbendpoint); int diff_y1 = R_ABS (y - xbendpoint); int diff_y2 = R_ABS (y2 - xbendpoint); draw_horizontal_line (c, x + 1, y, 1 + ybendpoint1 + 1, xbendpoint > y ? NRM_DOT : NRM_APEX); draw_vertical_line (c, x + 1 + ybendpoint1 + 1, miny1 + 1, diff_y1 - 1); draw_horizontal_line (c, x2 - ybendpoint2, xbendpoint, (x + 1 + ybendpoint1 + 1) - (x2 - ybendpoint2) + 1, xbendpoint > y ? REV_APEX_APEX : DOT_DOT); draw_vertical_line (c, x2 - ybendpoint2, miny2 + 1, diff_y2 - 1); draw_horizontal_line (c, x2 - ybendpoint2, y2, ybendpoint2 + 1, xbendpoint > y ? DOT_NRM : REV_APEX_NRM); } }
R_API void r_cons_canvas_line_square (RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style) { int min_x = R_MIN (x, x2); int diff_x = R_ABS (x - x2); int diff_y = R_ABS (y - y2); apply_line_style (c, x, y, x2, y2, style, 1); // -- // TODO: find if there's any collision in this line if (y2 - y > 1) { int hl = diff_y / 2 - 1; int hl2 = diff_y - hl; int w = diff_x == 0 ? 0 : diff_x + 1; int style = min_x == x ? APEX_DOT : DOT_APEX; draw_vertical_line (c, x, y + 1, hl); draw_vertical_line (c, x2, y + hl + 1, hl2); draw_horizontal_line (c, min_x, y + hl + 1, w, style); } else { if (y2 == y) { draw_horizontal_line (c, min_x, y, diff_x + 1, DOT_DOT); } else { if (x != x2) { draw_horizontal_line (c, min_x, y, diff_x + 1, REV_APEX_APEX); } draw_vertical_line (c, x2, y2, diff_y); } } c->attr = Color_RESET; }
void Canvas::draw_rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height) { draw_horizontal_line(x, y, width); draw_vertical_line(x + width, y, height); draw_vertical_line(x, y, height); draw_horizontal_line(x, y + height, width); }
void bmp_image::draw_filled_ellipse(int x0, int y0, int x1, int y1, rgba_color_t color) { //http://free.pages.at/easyfilter/bresenham.html int a = std::abs(x1-x0); int b = std::abs(y1-y0); int b1 = b & 1; /* values of diameter */ long dx = 4*(1-a)*b*b; int dy = 4*(b1+1)*a*a; /* error increment */ long err = dx+dy+b1*a*a, e2; /* error of 1.step */ if (x0 > x1) { /* if called with swapped points */ x0 = x1; x1 += a; } if (y0 > y1) { /* .. exchange them */ y0 = y1; } y0 += (b+1)/2; y1 = y0-b1; /* starting pixel */ a *= 8*a; b1 = 8*b*b; do { draw_horizontal_line(y0, x0, x1, color); draw_horizontal_line(y1, x0, x1, color); e2 = 2*err; if (e2 >= dx) { x0++; x1--; err += dx += b1; } /* x step */ if (e2 <= dy) { y0++; y1--; err += dy += a; } /* y step */ } while (x0 <= x1); while (y0-y1 < b) { /* too early stop of flat ellipses a=1 */ draw_horizontal_line(y0, x0-1, x1+1, color); draw_horizontal_line(y1, x0-1, x1+1, color); ++y0; --y1; } }
/* * standard filling algorithm */ void Triangle::doFill(PPM_Image &I, const PPM_Color &c) const { Point p1 {p1_}, p2 {p2_}, p3 {p3_}; if (p1.y() == p2.y() && p2.y() == p3.y()) return; // sort the vertices if (p1.y() > p2.y()) std::swap(p1, p2); if (p1.y() > p3.y()) std::swap(p1, p3); if (p2.y() > p3.y()) std::swap(p2, p3); // auxilliary variables int y1 {p1.y()}, y2 {p2.y()}, y3 {p3.y()}; const int x1 {p1.x()}, x2 {p2.x()}, x3 {p3.x()}, h {y3 - y1}; // height const int dx12 {x2- x1}, dx13 {x3 - x1}, dx23 {x3 - x2}; const int dy12 {y2- y1}, dy23 {y3 - y2}; const bool is_y12 {y1 == y2}; //const uint clr {c.color()}; for (int y {0}; y < h; ++y) { int xa = x1 + dx13 * (double(y) / h); // which part of the triangle int xb = (y > dy12 || is_y12) ? x2 + dx23 * (double(y-dy12) / dy23): x1 + dx12 * (double(y) / dy12); if (xa > xb) std::swap(xa, xb); // fill the triangle //const int y_cur {y1 + y}; draw_horizontal_line(I, c, xa, xb, y1 + y); //for (int x {xa}; x <= xb; ++x) // I[x][y_cur] = clr; } }
void display_scores(void){ set_display_attribute(BAR_COLOUR); draw_horizontal_line(HIGH_LABEL_Y,1,40); move_cursor(HIGH_LABEL_X,HIGH_LABEL_Y); printf_P(PSTR("HIGH SCORES")); move_cursor(TABLE_LABEL_X,TABLE_LABEL_Y); printf_P(PSTR(" Place | Score | User ")); move_cursor(TABLE_LABEL_X,TABLE_LABEL_Y+1); printf_P(PSTR("-----------------------------------")); struct highscore * scores = get_highscores(); uint8_t i = 0; while (i<SCORES && (scores+i)->score){ move_cursor(TABLE_LABEL_X,TABLE_LABEL_Y+2+i); printf_P(PSTR(" %d"),(i+1)); move_cursor(TABLE_LABEL_X+7,TABLE_LABEL_Y+2+i); printf_P(PSTR("| %d"),(scores+i)->score); move_cursor(TABLE_LABEL_X+21,TABLE_LABEL_Y+2+i); printf_P(PSTR("| %s"),(scores+i)->name); i++; } if (i == 0){ move_cursor(12,TABLE_LABEL_Y+3); printf_P(PSTR("No High Scores")); } move_cursor(WIDTH,HEIGHT); }
void Canvas::draw_roundrect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t radius) { uint8_t diameter = 2 * radius; int16_t f = 1 - radius; int16_t dx = 1; int16_t dy = -diameter; int8_t rx = 0; int8_t ry = radius; // Adjust position, width and height x += radius; y += radius; width -= diameter; height -= diameter; // Draw the boundary rectangle draw_horizontal_line(x, y - radius, width + 1); draw_vertical_line(x + width + radius, y, height + 1); draw_vertical_line(x - radius, y, height + 1); draw_horizontal_line(x, y + height + radius, width + 1); // Draw the round corners while (rx < ry) { if (f >= 0) { ry--; dy += 2; f += dy; } rx++; dx += 2; f += dx; draw_pixel(x + rx + width, y - ry); draw_pixel(x + ry + width, y - rx); draw_pixel(x + rx + width, y + ry + height); draw_pixel(x + ry + width, y + rx + height); draw_pixel(x - rx, y + ry + height); draw_pixel(x - ry, y + rx + height); draw_pixel(x - rx, y - ry); draw_pixel(x - ry, y - rx); } }
void Rectangle::doFill(PPM_Image &I, const PPM_Color &c) const { const int w {I.width() - 1}, h {I.height() - 1}; const int x1 = p_.x(), y1 = p_.y(); const int xmin {std::min(std::max(0, x1), w)}; const int xmax {std::min(std::max(0, x1 + int(w_)), w)}; //const uint clr {c.color()}; for (auto y = std::min(std::max(0, y1), h); y <= std::min(std::max(0, y1 + int(h_)), h); ++y) draw_horizontal_line(I, c, xmin, xmax, y); //for (auto x = xmin; x < xmax; ++x) // I[x][y] = clr; }
void bmp_image::draw_filled_circle(int x0, int y0, int radius, rgba_color_t color) { assert(radius >= 0); //Midpoint circle algorithm //std::cout << x0 << ", " << y0 << ", " << radius << ", " << std::hex << color << std::endl; int f = 1 - radius; int ddF_x = 1; int ddF_y = -2 * radius; int x = 0; int y = radius; draw_horizontal_line(y0, x0 - radius, x0 + radius, color); draw_vertical_line(x0, y0 - radius, y0 + radius, color); while(x < y) { if(f >= 0) { y--; ddF_y += 2; f += ddF_y; } x++; ddF_x += 2; f += ddF_x; draw_horizontal_line(y0 + y, x0 - x, x0 + x, color); draw_horizontal_line(y0 - y, x0 - x, x0 + x, color); draw_horizontal_line(y0 + x, x0 - y, x0 + y, color); draw_horizontal_line(y0 - x, x0 - y, x0 + y, color); } }
/* The following function divides the GLCD display panel into * equal number of rows based on the first value passed and * equal number of columns based on the second value passed * as arguments. */ draw_grid(int x, int y) { int horizontal_lines, vertical_lines; int i; horizontal_lines = GLCD_ROWS/x; for(i=0; i<(x+1); i++) { draw_horizontal_line(horizontal_lines*i); } vertical_lines = GLCD_COLUMNS/y; for(i=0; i<(x+1); i++) { draw_vertical_line(vertical_lines*i); } }
void draw_grid(){ int hpos; //счётчик int ypos; //счётчик int grid_height=(cell_height+1)*row_num+1; int grid_width=(cell_width+1)*col_num+1; for (ypos=0;ypos<grid_width;ypos++){ if (ypos % (cell_width+1) == 0){ draw_vertical_line(pimg,ypos, grid_height); } } for (hpos=0;hpos<grid_height;hpos++){ if (hpos % (cell_height+1) == 0){ //+1 т.к. 1 пиксель между ячейками (граница) draw_horizontal_line(pimg,hpos, grid_width); } } }
R_API void r_cons_canvas_line_square_defined (RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style, int bendpoint, int isvert) { int min_x = R_MIN (x, x2); int diff_x = R_ABS (x - x2); int diff_y = R_ABS (y - y2); int min_y = R_MIN (y, y2); apply_line_style (c, x, y, x2, y2, style, isvert); if (isvert) { if (x2 == x) { draw_vertical_line (c, x, y + 1, diff_y); } else if (y2 - y > 1) { int h1 = 1 + bendpoint; int h2 = diff_y - h1; int w = diff_x == 0 ? 0 : diff_x + 1; int style = min_x == x ? APEX_DOT : DOT_APEX; draw_vertical_line (c, x, y + 1, h1); draw_horizontal_line (c, min_x, y + bendpoint + 2, w, style); draw_vertical_line (c, x2, y + h1 + 1 + 1, h2); } else { //TODO: currently copy-pasted if (y2 == y) { draw_horizontal_line (c, min_x, y, diff_x + 1, DOT_DOT); } else { if (x != x2) { draw_horizontal_line (c, min_x, y, diff_x + 1, REV_APEX_APEX); } draw_vertical_line (c, x2, y2, diff_y-2); } } } else { if (y2 == y) { draw_horizontal_line (c, min_x + 1, y, diff_x, NRM_NRM); } else if (x2 - x > 1) { int w1 = 1 + bendpoint; int w2 = diff_x - w1; //int h = diff_x;// == 0 ? 0 : diff_x + 1; //int style = min_x == x ? APEX_DOT : DOT_APEX; //draw_vertical_line (c, x, y + 1, h1); draw_horizontal_line (c, x + 1, y, w1 + 1, y2 > y ? NRM_DOT : NRM_APEX); //draw_horizontal_line (c, min_x, y + bendpoint + 2, w, style); draw_vertical_line (c, x + 1 + w1, min_y + 1, diff_y - 1); //draw_vertical_line (c, x2, y + h1 + 1 + 1, h2); draw_horizontal_line (c, x + 1 + w1, y2, w2, y2 < y ? DOT_NRM : REV_APEX_NRM); } } c->attr = Color_RESET; }
void reset_terminal(void){ clear_terminal(); set_display_attribute(BAR_COLOUR); draw_horizontal_line(1,1,WIDTH); set_display_attribute(BAR_COLOUR); draw_vertical_line(40,1,HEIGHT); move_cursor(TITLE_X,TITLE_Y); printf_P(PSTR("FROGGER")); draw_lives(); draw_score(); draw_level(); draw_time(16); display_scores(); draw_status(0); draw_frog(); set_display_attribute(8); }
void Gradient::resize(float width, float height) { float w; if(direction == LEFT_RIGHT) w = width; else if(direction == TOP_BOTTOM) w = height; else assert(false); float dr = ((float) to.r - (float) from.r) / w; float dg = ((float) to.g - (float) from.g) / w; float db = ((float) to.b - (float) from.b) / w; float da = ((float) to.a - (float) from.a) / w; #if SDL_BYTEORDER == SDL_BIG_ENDIAN SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE, (int) width, (int) height, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); #else SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE, (int) width, (int) height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); #endif if(surface == 0) throw std::runtime_error("Couldn't create SDL_Surface for gradient. " "(Out of memory?"); float r = from.r; float g = from.g; float b = from.b; float a = from.a; if(direction == LEFT_RIGHT) { for(int x = 0; x < (int) width; ++x) { draw_vertical_line(surface, x, 0, (int) height, lrintf(r), lrintf(g), lrintf(b), lrintf(a)); r += dr; g += dg; b += db; a += da; } } else { for(int y = 0; y < (int) height; ++y) { draw_horizontal_line(surface, 0, y, (int) width, lrintf(r), lrintf(g), lrintf(b), lrintf(a)); r += dr; g += dg; b += db; a += da; } } texture.reset(texture_manager->create(surface)); this->width = width; this->height = height; }
void Rectangle::doDraw(PPM_Image &I, const PPM_Color &c) const { const int x1 = p_.x(), x2 = x1 + w_, y1 = p_.y(), y2 = y1 + h_; const int w {I.width() - 1}, h {I.height() - 1}; const int xmin {std::min(std::max(0, x1), w)}; const int xmax {std::min(std::max(0, x2), w)}; const int ymin {std::min(std::max(0, y1), h)}; const int ymax {std::min(std::max(0, y2), h)}; const uint clr {c.color()}; /* drawing all sides: if the rectangle goes beyond the image size, then * drawing lines on the image border */ //for (auto x = xmin; x <= xmax; ++x) { // I[x][ymin] = clr; // I[x][ymax] = clr; //} //for (auto y = ymin; y <= ymax; ++y) { // I[xmin][y] = clr; // I[xmax][y] = clr; //} // avoid drawing lines on the border if (y1 >= 0) { if (y2 < h) for (auto x = xmin; x <= xmax; ++x) { I[x][y1] = clr; I[x][y2] = clr; } else if (y1 <= h) draw_horizontal_line(I, c, xmin, xmax, y1); //for (auto x = xmin; x <= xmax; ++x) // I[x][y1] = clr; } else if (y2 >= 0 && y2 < h) draw_horizontal_line(I, c, xmin, xmax, y2); //for (auto x = xmin; x <= xmax; ++x) // I[x][y2] = clr; if (x1 >= 0) { if (x2 < w) for (auto y = ymin; y <= ymax; ++y) { I[x1][y] = clr; I[x2][y] = clr; } else if (x1 <= w) draw_vertical_line(I, c, x1, ymin, ymax); //for (auto y = ymin; y <= ymax; ++y) // I[x1][y] = clr; } else if (x2 >= 0 && x2 < w) draw_vertical_line(I, c, x2, ymin, ymax); //for (auto y = ymin; y <= ymax; ++y) // I[x2][y] = clr; // the code below is shorter than above, but, perhaps, less efficient //if (y1 >= 0 && y1 < h) // draw_horizontal_line(I, c, xmin, xmax, y1); //if (y2 >= 0 && y2 < h) // draw_horizontal_line(I, c, xmin, xmax, y2); //if (x1 >= 0 && x1 < w) // draw_vertical_line(I, c, x1, ymin, ymax); //if (x2 >= 0 && x2 < w) // draw_vertical_line(I, c, x2, ymin, ymax); }
void clip_n_draw_horizontal_line(PPM_Image &I, const PPM_Color &c, const int x1, const int x2, const int y) { const int w {I.width() - 1}; draw_horizontal_line(I, c, std::min(std::max(0, x1), w), std::min(std::max(0, x2), w), y); }