diff --git a/src/graph.c b/src/graph.c index 04db35c8..0af8c078 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1366,7 +1366,7 @@ int Circle_squared_diameter(int diameter) // -- Tracer général d'une ellipse vide ----------------------------------- -void Draw_empty_ellipse_general(short center_x,short center_y,short horizontal_radius,short vertical_radius,byte color) +static void Draw_empty_ellipse_general(short center_x,short center_y,short horizontal_radius,short vertical_radius,byte color) { short start_x; short start_y; @@ -1445,6 +1445,78 @@ void Draw_empty_ellipse_general(short center_x,short center_y,short horizontal_r Update_part_of_screen(center_x-horizontal_radius,center_y-vertical_radius,2*horizontal_radius+1,2*vertical_radius+1); } +static void Draw_inscribed_ellipse_general(short x1, short y1, short x2, short y2, byte color, byte filled) +{ + short left, right, top, bottom; + short dbl_center_x; // double of center_x + short dbl_center_y; // double of center_y + short dbl_x_radius; // double of horizontal radius + short dbl_y_radius; // double of vertical radius + long sq_dbl_x_radius; + long sq_dbl_y_radius; + qword sq_dbl_radius_product; + short x_pos; + short y_pos; + short x_max; + + if (x1 > x2) + { + left = x2; + right = x1; + } + else + { + left = x1; + right = x2; + } + if (y1 > y2) + { + top = y2; + bottom = y1; + } + else + { + top = y1; + bottom = y2; + } + dbl_center_x = left+right; + dbl_center_y = top+bottom; + dbl_x_radius = right-left+1; + dbl_y_radius = bottom-top+1; + sq_dbl_x_radius = (long)dbl_x_radius*dbl_x_radius; + sq_dbl_y_radius = (long)dbl_y_radius*dbl_y_radius; + sq_dbl_radius_product = (qword)sq_dbl_x_radius * sq_dbl_y_radius; + + x_max = right; + for (y_pos = top; y_pos <= (dbl_center_y >> 1); y_pos++) + { + long dbl_y = 2*y_pos - dbl_center_y; + long sq_dbl_y = dbl_y*dbl_y; + for (x_pos = left; x_pos <= (dbl_center_x >> 1); x_pos++) + { + long dbl_x = 2*x_pos - dbl_center_x; + long sq_dbl_x = dbl_x*dbl_x; + if (((qword)sq_dbl_x * sq_dbl_y_radius + (qword)sq_dbl_y * sq_dbl_x_radius) < sq_dbl_radius_product) + { + short x_pos_backup = x_pos; + do + { + Pixel_figure(x_pos,y_pos,color); + Pixel_figure(dbl_center_x - x_pos,y_pos,color); + Pixel_figure(x_pos,dbl_center_y - y_pos,color); + Pixel_figure(dbl_center_x - x_pos,dbl_center_y - y_pos,color); + x_pos++; + } + while (x_pos <= (dbl_center_x >> 1) && x_pos < x_max); + if (!filled && x_pos_backup < x_max) + x_max = x_pos_backup; + break; + } + } + } + + Update_part_of_screen(left, top, right-left, bottom-top); +} // -- Tracé définitif d'une ellipse vide -- void Draw_empty_ellipse_permanent(short center_x,short center_y,short horizontal_radius,short vertical_radius,byte color) @@ -1452,7 +1524,14 @@ void Draw_empty_ellipse_permanent(short center_x,short center_y,short horizontal Pixel_figure=Pixel_figure_permanent; Init_permanent_draw(); Draw_empty_ellipse_general(center_x,center_y,horizontal_radius,vertical_radius,color); - Update_part_of_screen(center_x - horizontal_radius, center_y - vertical_radius, 2* horizontal_radius+1, 2*vertical_radius+1); + //Update_part_of_screen(center_x - horizontal_radius, center_y - vertical_radius, 2* horizontal_radius+1, 2*vertical_radius+1); +} + +void Draw_empty_inscribed_ellipse_permanent(short x1,short y1,short x2, short y2,byte color) +{ + Pixel_figure=Pixel_figure_permanent; + Init_permanent_draw(); + Draw_inscribed_ellipse_general(x1, y1, x2, y2, color, 0); } // -- Tracer la preview d'une ellipse vide -- @@ -1461,7 +1540,13 @@ void Draw_empty_ellipse_preview(short center_x,short center_y,short horizontal_r { Pixel_figure=Pixel_figure_preview; Draw_empty_ellipse_general(center_x,center_y,horizontal_radius,vertical_radius,color); - Update_part_of_screen(center_x - horizontal_radius, center_y - vertical_radius, 2* horizontal_radius+1, 2*vertical_radius +1); + //Update_part_of_screen(center_x - horizontal_radius, center_y - vertical_radius, 2* horizontal_radius+1, 2*vertical_radius +1); +} + +void Draw_empty_inscribed_ellipse_preview(short x1,short y1,short x2,short y2,byte color) +{ + Pixel_figure=Pixel_figure_preview; + Draw_inscribed_ellipse_general(x1, y1, x2, y2, color, 0); } // -- Effacer la preview d'une ellipse vide -- @@ -1470,7 +1555,13 @@ void Hide_empty_ellipse_preview(short center_x,short center_y,short horizontal_r { Pixel_figure=Pixel_figure_clear_preview; Draw_empty_ellipse_general(center_x,center_y,horizontal_radius,vertical_radius,0); - Update_part_of_screen(center_x - horizontal_radius, center_y - vertical_radius, 2* horizontal_radius+1, 2*vertical_radius+1); + //Update_part_of_screen(center_x - horizontal_radius, center_y - vertical_radius, 2* horizontal_radius+1, 2*vertical_radius+1); +} + +void Hide_empty_inscribed_ellipse_preview(short x1,short y1,short x2,short y2) +{ + Pixel_figure=Pixel_figure_clear_preview; + Draw_inscribed_ellipse_general(x1,y1,x2,y2,0,0); } // -- Tracer une ellipse pleine -- @@ -1512,6 +1603,12 @@ void Draw_filled_ellipse(short center_x,short center_y,short horizontal_radius,s Update_part_of_screen(center_x-horizontal_radius,center_y-vertical_radius,2*horizontal_radius+1,2*vertical_radius+1); } +void Draw_filled_inscribed_ellipse(short x1,short y1,short x2,short y2,byte color) +{ + Pixel_figure = Pixel_clipped; + Draw_inscribed_ellipse_general(x1, y1, x2, y2, color, 1); +} + /****************** * TRACÉ DE LIGNES * ******************/ diff --git a/src/graph.h b/src/graph.h index f999b597..c298652f 100644 --- a/src/graph.h +++ b/src/graph.h @@ -75,6 +75,11 @@ void Draw_empty_ellipse_preview (short center_x,short center_y,short horizontal void Hide_empty_ellipse_preview (short center_x,short center_y,short horizontal_radius,short vertical_radius); void Draw_filled_ellipse (short center_x,short center_y,short horizontal_radius,short vertical_radius,byte color); +void Draw_empty_inscribed_ellipse_permanent(short x1,short y1,short x2, short y2,byte color); +void Draw_empty_inscribed_ellipse_preview(short x1,short y1,short x2,short y2,byte color); +void Hide_empty_inscribed_ellipse_preview(short x1,short y1,short x2,short y2); +void Draw_filled_inscribed_ellipse(short x1,short y1,short x2,short y2,byte color); + void Clamp_coordinates_regular_angle(short ax, short ay, short* bx, short* by); void Draw_line_general(short start_x,short start_y,short end_x,short end_y, byte color); void Draw_line_permanent (short start_x,short start_y,short end_x,short end_y,byte color); diff --git a/src/operatio.c b/src/operatio.c index bcd13bf3..9088cf5e 100644 --- a/src/operatio.c +++ b/src/operatio.c @@ -45,6 +45,13 @@ #define M_PI 3.14159265358979323846 #endif +/// when this macro is defined, the ellipses are inscribed in +/// the rectangle of the mouse button press position and the +/// release position. +/// Otherwise, the mouse button press position is the center and +/// the release postion defines the vertical and horizontal radiuses. +#define INSCRIBED_ELLIPSE + /// Time (in SDL ticks) when the next airbrush drawing should be done. Also used /// for discontinuous freehand drawing. Uint32 Airbrush_next_time; @@ -1172,8 +1179,10 @@ void Ellipse_12_5(void) short center_x; short center_y; short color; +#ifndef INSCRIBED_ELLIPSE short horizontal_radius; short vertical_radius; +#endif Operation_pop(&tangent_y); Operation_pop(&tangent_x); @@ -1185,9 +1194,12 @@ void Ellipse_12_5(void) if ( (tangent_x!=Paintbrush_X) || (tangent_y!=Paintbrush_Y) ) { Hide_cursor(); +#ifndef INSCRIBED_ELLIPSE Cursor_shape=CURSOR_SHAPE_TARGET; +#endif Display_coords_rel_or_abs(center_x,center_y); +#ifndef INSCRIBED_ELLIPSE horizontal_radius=(tangent_x>center_x)?tangent_x-center_x :center_x-tangent_x; vertical_radius =(tangent_y>center_y)?tangent_y-center_y @@ -1199,6 +1211,10 @@ void Ellipse_12_5(void) vertical_radius =(Paintbrush_Y>center_y)?Paintbrush_Y-center_y :center_y-Paintbrush_Y; Draw_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius,color); +#else + Hide_empty_inscribed_ellipse_preview(center_x,center_y,tangent_x,tangent_y); + Draw_empty_inscribed_ellipse_preview(center_x,center_y,Paintbrush_X,Paintbrush_Y,color); +#endif Display_cursor(); } @@ -1225,8 +1241,10 @@ void Empty_ellipse_0_5(void) short center_x; short center_y; short color; +#ifndef INSCRIBED_ELLIPSE short horizontal_radius; short vertical_radius; +#endif Operation_pop(&tangent_y); Operation_pop(&tangent_x); @@ -1234,15 +1252,23 @@ void Empty_ellipse_0_5(void) Operation_pop(¢er_x); Operation_pop(&color); +#ifndef INSCRIBED_ELLIPSE horizontal_radius=(tangent_x>center_x)?tangent_x-center_x :center_x-tangent_x; vertical_radius =(tangent_y>center_y)?tangent_y-center_y :center_y-tangent_y; Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); +#else + Hide_empty_inscribed_ellipse_preview(center_x,center_y,tangent_x,tangent_y); +#endif Paintbrush_shape=Paintbrush_shape_before_operation; +#ifndef INSCRIBED_ELLIPSE Draw_empty_ellipse_permanent(center_x,center_y,horizontal_radius,vertical_radius,color); +#else + Draw_empty_inscribed_ellipse_permanent(center_x,center_y,tangent_x,tangent_y,color); +#endif End_of_modification(); @@ -1269,8 +1295,10 @@ void Filled_ellipse_0_5(void) short center_x; short center_y; short color; +#ifndef INSCRIBED_ELLIPSE short horizontal_radius; short vertical_radius; +#endif Operation_pop(&tangent_y); Operation_pop(&tangent_x); @@ -1278,15 +1306,23 @@ void Filled_ellipse_0_5(void) Operation_pop(¢er_x); Operation_pop(&color); +#ifndef INSCRIBED_ELLIPSE horizontal_radius=(tangent_x>center_x)?tangent_x-center_x :center_x-tangent_x; vertical_radius =(tangent_y>center_y)?tangent_y-center_y :center_y-tangent_y; Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); +#else + Hide_empty_inscribed_ellipse_preview(center_x,center_y,tangent_x,tangent_y); +#endif Paintbrush_shape=Paintbrush_shape_before_operation; +#ifndef INSCRIBED_ELLIPSE Draw_filled_ellipse(center_x,center_y,horizontal_radius,vertical_radius,color); +#else + Draw_filled_inscribed_ellipse(center_x,center_y,tangent_x,tangent_y,color); +#endif End_of_modification(); if ( (Config.Coords_rel) && (Menu_is_visible) )