From cd464e98387859ee447a425c4319eab7cd655694 Mon Sep 17 00:00:00 2001 From: Tom Gilbert Date: Fri, 8 Sep 2000 14:47:36 +0000 Subject: [PATCH] Much faster polygon clipping, made span() more sensible. Added the function: unsigned char imlib_polygon_contains_point(ImlibPolygon poly, int x, int y); Tells you if a point lies in a polygon. Handy for apps that might want to test for "selection" of a polygon shape or something... SVN revision: 3355 --- src/Imlib2.h | 2 + src/api.c | 189 +++++++++++++++-------------------- src/rgbadraw.c | 260 ++++++++++++++++++++++++++++++++----------------- src/rgbadraw.h | 19 +++- 4 files changed, 266 insertions(+), 204 deletions(-) diff --git a/src/Imlib2.h b/src/Imlib2.h index 4591583..7d0fba1 100644 --- a/src/Imlib2.h +++ b/src/Imlib2.h @@ -334,6 +334,8 @@ extern "C" void imlib_image_fill_polygon(ImlibPolygon poly); void imlib_polygon_get_bounds(ImlibPolygon poly, int *px1, int *py1, int *px2, int *py2); + unsigned char imlib_polygon_contains_point(ImlibPolygon poly, int x, + int y); /* ellipses */ void imlib_image_draw_ellipse(int xc, int yc, int a, int b); diff --git a/src/api.c b/src/api.c index f5dae13..c1ff56b 100644 --- a/src/api.c +++ b/src/api.c @@ -140,8 +140,7 @@ imlib_context_set_colormap(Colormap colormap) ctxt_colormap = colormap; } -Colormap -imlib_context_get_colormap(void) +Colormap imlib_context_get_colormap(void) { return ctxt_colormap; } @@ -152,8 +151,7 @@ imlib_context_set_drawable(Drawable drawable) ctxt_drawable = drawable; } -Drawable -imlib_context_get_drawable(void) +Drawable imlib_context_get_drawable(void) { return ctxt_drawable; } @@ -164,8 +162,7 @@ imlib_context_set_mask(Pixmap mask) ctxt_mask = mask; } -Pixmap -imlib_context_get_mask(void) +Pixmap imlib_context_get_mask(void) { return ctxt_mask; } @@ -224,8 +221,7 @@ imlib_context_set_color_modifier(Imlib_Color_Modifier color_modifier) ctxt_color_modifier = color_modifier; } -Imlib_Color_Modifier -imlib_context_get_color_modifier(void) +Imlib_Color_Modifier imlib_context_get_color_modifier(void) { return ctxt_color_modifier; } @@ -236,8 +232,7 @@ imlib_context_set_operation(Imlib_Operation operation) ctxt_operation = operation; } -Imlib_Operation -imlib_context_get_operation(void) +Imlib_Operation imlib_context_get_operation(void) { return ctxt_operation; } @@ -248,8 +243,7 @@ imlib_context_set_font(Imlib_Font font) ctxt_font = font; } -Imlib_Font -imlib_context_get_font(void) +Imlib_Font imlib_context_get_font(void) { return ctxt_font; } @@ -272,8 +266,7 @@ imlib_context_get_angle(void) return ctxt_angle; } -Imlib_Text_Direction -imlib_context_get_direction(void) +Imlib_Text_Direction imlib_context_get_direction(void) { return ctxt_direction; } @@ -308,8 +301,7 @@ imlib_context_set_color_range(Imlib_Color_Range color_range) ctxt_color_range = color_range; } -Imlib_Color_Range -imlib_context_get_color_range(void) +Imlib_Color_Range imlib_context_get_color_range(void) { return ctxt_color_range; } @@ -320,8 +312,7 @@ imlib_context_set_progress_function(Imlib_Progress_Function progress_function) ctxt_progress_func = progress_function; } -Imlib_Progress_Function -imlib_context_get_progress_function(void) +Imlib_Progress_Function imlib_context_get_progress_function(void) { return ctxt_progress_func; } @@ -344,8 +335,7 @@ imlib_context_set_image(Imlib_Image image) ctxt_image = image; } -Imlib_Image -imlib_context_get_image(void) +Imlib_Image imlib_context_get_image(void) { return ctxt_image; } @@ -405,8 +395,7 @@ imlib_get_best_visual(Display * display, int screen, int *depth_return) return __imlib_BestVisual(display, screen, depth_return); } -Imlib_Image -imlib_load_image(const char *file) +Imlib_Image imlib_load_image(const char *file) { Imlib_Image im = NULL; Imlib_Image prev_ctxt_image; @@ -420,8 +409,7 @@ imlib_load_image(const char *file) return (Imlib_Image) im; } -Imlib_Image -imlib_load_image_immediately(const char *file) +Imlib_Image imlib_load_image_immediately(const char *file) { Imlib_Image im = NULL; Imlib_Image prev_ctxt_image; @@ -436,8 +424,7 @@ imlib_load_image_immediately(const char *file) return (Imlib_Image) im; } -Imlib_Image -imlib_load_image_without_cache(const char *file) +Imlib_Image imlib_load_image_without_cache(const char *file) { Imlib_Image im = NULL; Imlib_Image prev_ctxt_image; @@ -452,8 +439,7 @@ imlib_load_image_without_cache(const char *file) return (Imlib_Image) im; } -Imlib_Image -imlib_load_image_immediately_without_cache(const char *file) +Imlib_Image imlib_load_image_immediately_without_cache(const char *file) { Imlib_Image im = NULL; Imlib_Image prev_ctxt_image; @@ -468,9 +454,9 @@ imlib_load_image_immediately_without_cache(const char *file) return (Imlib_Image) im; } -Imlib_Image -imlib_load_image_with_error_return(const char *file, - Imlib_Load_Error * error_return) +Imlib_Image imlib_load_image_with_error_return(const char *file, + Imlib_Load_Error * + error_return) { Imlib_Image im = NULL; ImlibLoadError er; @@ -910,8 +896,7 @@ imlib_blend_image_onto_image(Imlib_Image source_image, char merge_alpha, ctxt_color_modifier, ctxt_operation); } -Imlib_Image -imlib_create_image(int width, int height) +Imlib_Image imlib_create_image(int width, int height) { DATA32 *data; @@ -923,8 +908,8 @@ imlib_create_image(int width, int height) return NULL; } -Imlib_Image -imlib_create_image_using_data(int width, int height, DATA32 * data) +Imlib_Image imlib_create_image_using_data(int width, int height, + DATA32 * data) { ImlibImage *im; @@ -938,8 +923,8 @@ imlib_create_image_using_data(int width, int height, DATA32 * data) return (Imlib_Image) im; } -Imlib_Image -imlib_create_image_using_copied_data(int width, int height, DATA32 * data) +Imlib_Image imlib_create_image_using_copied_data(int width, int height, + DATA32 * data) { ImlibImage *im; @@ -961,9 +946,9 @@ imlib_create_image_using_copied_data(int width, int height, DATA32 * data) return NULL; } -Imlib_Image -imlib_create_image_from_drawable(Pixmap mask, int x, int y, int width, - int height, char need_to_grab_x) +Imlib_Image imlib_create_image_from_drawable(Pixmap mask, int x, int y, + int width, int height, + char need_to_grab_x) { ImlibImage *im; char domask = 0; @@ -979,14 +964,14 @@ imlib_create_image_from_drawable(Pixmap mask, int x, int y, int width, return (Imlib_Image) im; } -Imlib_Image -imlib_create_scaled_image_from_drawable(Pixmap mask, int source_x, - int source_y, int source_width, - int source_height, - int destination_width, - int destination_height, - char need_to_grab_x, - char get_mask_from_shape) +Imlib_Image imlib_create_scaled_image_from_drawable(Pixmap mask, int source_x, + int source_y, + int source_width, + int source_height, + int destination_width, + int destination_height, + char need_to_grab_x, + char get_mask_from_shape) { ImlibImage *im; char domask = 0, tmpmask = 0; @@ -1135,8 +1120,7 @@ imlib_copy_drawable_to_image(Pixmap mask, int x, int y, int width, int height, height, domask, need_to_grab_x); } -Imlib_Image -imlib_clone_image(void) +Imlib_Image imlib_clone_image(void) { ImlibImage *im, *im_old; @@ -1175,8 +1159,7 @@ imlib_clone_image(void) return (Imlib_Image) im; } -Imlib_Image -imlib_create_cropped_image(int x, int y, int width, int height) +Imlib_Image imlib_create_cropped_image(int x, int y, int width, int height) { ImlibImage *im, *im_old; @@ -1200,11 +1183,11 @@ imlib_create_cropped_image(int x, int y, int width, int height) return (Imlib_Image) im; } -Imlib_Image -imlib_create_cropped_scaled_image(int source_x, int source_y, - int source_width, int source_height, - int destination_width, - int destination_height) +Imlib_Image imlib_create_cropped_scaled_image(int source_x, int source_y, + int source_width, + int source_height, + int destination_width, + int destination_height) { ImlibImage *im, *im_old; @@ -1243,8 +1226,7 @@ imlib_create_cropped_scaled_image(int source_x, int source_y, return (Imlib_Image) im; } -Imlib_Updates -imlib_updates_clone(Imlib_Updates updates) +Imlib_Updates imlib_updates_clone(Imlib_Updates updates) { ImlibUpdate *u; @@ -1252,8 +1234,8 @@ imlib_updates_clone(Imlib_Updates updates) return (Imlib_Updates) __imlib_DupUpdates(u); } -Imlib_Updates -imlib_update_append_rect(Imlib_Updates updates, int x, int y, int w, int h) +Imlib_Updates imlib_update_append_rect(Imlib_Updates updates, int x, int y, + int w, int h) { ImlibUpdate *u; @@ -1261,8 +1243,7 @@ imlib_update_append_rect(Imlib_Updates updates, int x, int y, int w, int h) return (Imlib_Updates) __imlib_AddUpdate(u, x, y, w, h); } -Imlib_Updates -imlib_updates_merge(Imlib_Updates updates, int w, int h) +Imlib_Updates imlib_updates_merge(Imlib_Updates updates, int w, int h) { ImlibUpdate *u; @@ -1270,8 +1251,8 @@ imlib_updates_merge(Imlib_Updates updates, int w, int h) return (Imlib_Updates) __imlib_MergeUpdate(u, w, h, 0); } -Imlib_Updates -imlib_updates_merge_for_rendering(Imlib_Updates updates, int w, int h) +Imlib_Updates imlib_updates_merge_for_rendering(Imlib_Updates updates, int w, + int h) { ImlibUpdate *u; @@ -1288,8 +1269,7 @@ imlib_updates_free(Imlib_Updates updates) __imlib_FreeUpdates(u); } -Imlib_Updates -imlib_updates_get_next(Imlib_Updates updates) +Imlib_Updates imlib_updates_get_next(Imlib_Updates updates) { ImlibUpdate *u; @@ -1357,15 +1337,13 @@ imlib_render_image_updates_on_drawable(Imlib_Updates updates, int x, int y) __imlib_SetMaxXImageCount(ctxt_display, 0); } -Imlib_Updates -imlib_updates_init(void) +Imlib_Updates imlib_updates_init(void) { return (Imlib_Updates) NULL; } -Imlib_Updates -imlib_updates_append_updates(Imlib_Updates updates, - Imlib_Updates appended_updates) +Imlib_Updates imlib_updates_append_updates(Imlib_Updates updates, + Imlib_Updates appended_updates) { ImlibUpdate *u, *uu; @@ -1558,8 +1536,7 @@ imlib_image_tile(void) __imlib_TileImageVert(im); } -Imlib_Font -imlib_load_font(const char *font_name) +Imlib_Font imlib_load_font(const char *font_name) { return (Imlib_Font) __imlib_load_font(font_name); } @@ -1945,8 +1922,7 @@ imlib_get_maximum_font_descent(void) return ((ImlibFont *) ctxt_font)->max_ascent; } -Imlib_Color_Modifier -imlib_create_color_modifier(void) +Imlib_Color_Modifier imlib_create_color_modifier(void) { return (Imlib_Color_Modifier) __imlib_CreateCmod(); } @@ -2077,8 +2053,8 @@ imlib_apply_color_modifier_to_rectangle(int x, int y, int width, int height) (ImlibColorModifier *) ctxt_color_modifier); } -Imlib_Updates -imlib_image_draw_line(int x1, int y1, int x2, int y2, char make_updates) +Imlib_Updates imlib_image_draw_line(int x1, int y1, int x2, int y2, + char make_updates) { ImlibImage *im; @@ -2101,12 +2077,13 @@ imlib_image_draw_line(int x1, int y1, int x2, int y2, char make_updates) ctxt_cliprect.y + ctxt_cliprect.h, (DATA8) ctxt_color.red, - (DATA8) ctxt_color. - green, - (DATA8) ctxt_color. - blue, - (DATA8) ctxt_color. - alpha, ctxt_operation, + (DATA8) + ctxt_color.green, + (DATA8) + ctxt_color.blue, + (DATA8) + ctxt_color.alpha, + ctxt_operation, (char) make_updates); } else @@ -2281,8 +2258,7 @@ imlib_image_copy_rect(int x, int y, int width, int height, int new_x, __imlib_copy_image_data(im, x, y, width, height, new_x, new_y); } -Imlib_Color_Range -imlib_create_color_range(void) +Imlib_Color_Range imlib_create_color_range(void) { return (Imlib_Color_Range) __imlib_CreateRange(); } @@ -2475,8 +2451,7 @@ imlib_save_image_with_error_return(const char *filename, ctxt_image = prev_ctxt_image; } -Imlib_Image -imlib_create_rotated_image(double angle) +Imlib_Image imlib_create_rotated_image(double angle) { ImlibImage *im, *im_old; DATA32 *data; @@ -2653,8 +2628,7 @@ imlib_image_filter(void) __imlib_FilterImage(im, (ImlibFilter *) ctxt_filter); } -Imlib_Filter -imlib_create_filter(int initsize) +Imlib_Filter imlib_create_filter(int initsize) { return (Imlib_Filter) __imlib_CreateFilter(initsize); } @@ -2673,8 +2647,7 @@ imlib_context_set_filter(Imlib_Filter filter) ctxt_filter = filter; } -Imlib_Filter -imlib_context_get_filter(void) +Imlib_Filter imlib_context_get_filter(void) { return ctxt_filter; } @@ -2761,8 +2734,7 @@ imlib_apply_filter(char *script, ...) va_end(param_list); } -ImlibPolygon -imlib_polygon_new(void) +ImlibPolygon imlib_polygon_new(void) { return (ImlibPolygon) __imlib_polygon_new(); } @@ -2824,21 +2796,13 @@ imlib_image_fill_polygon(ImlibPolygon poly) return; __imlib_DirtyImage(im); __imlib_DirtyPixmapsForImage(im); - if (ctxt_cliprect.w) - { - __imlib_draw_polygon_filled_clipped(im, poly, ctxt_cliprect.x, - ctxt_cliprect.x + ctxt_cliprect.w, - ctxt_cliprect.y, - ctxt_cliprect.y + ctxt_cliprect.h, - ctxt_color.red, ctxt_color.green, - ctxt_color.blue, ctxt_color.alpha, - ctxt_operation); - } - else - { - __imlib_draw_polygon_filled(im, poly, ctxt_color.red, ctxt_color.green, - ctxt_color.blue, ctxt_color.alpha, ctxt_operation); - } + __imlib_draw_polygon_filled(im, poly, ctxt_cliprect.x, + ctxt_cliprect.x + ctxt_cliprect.w, + ctxt_cliprect.y, + ctxt_cliprect.y + ctxt_cliprect.h, + ctxt_color.red, ctxt_color.green, + ctxt_color.blue, ctxt_color.alpha, + ctxt_operation); } @@ -2912,3 +2876,10 @@ imlib_image_fill_ellipse(int xc, int yc, int a, int b) } } + +unsigned char +imlib_polygon_contains_point(ImlibPolygon poly, int x, int y) +{ + CHECK_PARAM_POINTER("imlib_polygon_contains_point", "polygon", poly); + return __imlib_polygon_contains_point(poly, x, y); +} diff --git a/src/rgbadraw.c b/src/rgbadraw.c index f305f80..750ea08 100644 --- a/src/rgbadraw.c +++ b/src/rgbadraw.c @@ -14,6 +14,7 @@ (((x) >= (rx)) && ((y) >= (ry)) && ((x) <= ((rx) + (rw))) && ((y) <= ((ry) + (rh)))) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define round(a) floor(a+0.5) @@ -110,7 +111,7 @@ __imlib_FlipImageDiagonal(ImlibImage * im, int direction) switch (direction) { default: - case 0: /*\ DOWN_RIGHT \ */ + case 0: /*\ DOWN_RIGHT \ */ tmp = im->border.top; im->border.top = im->border.left; im->border.left = tmp; @@ -120,7 +121,7 @@ __imlib_FlipImageDiagonal(ImlibImage * im, int direction) to = data; hw = -hw + 1; break; - case 1: /*\ DOWN_LEFT \ */ + case 1: /*\ DOWN_LEFT \ */ tmp = im->border.top; im->border.top = im->border.left; im->border.left = im->border.bottom; @@ -129,7 +130,7 @@ __imlib_FlipImageDiagonal(ImlibImage * im, int direction) to = data + w - 1; hw = -hw - 1; break; - case 2: /*\ UP_RIGHT \ */ + case 2: /*\ UP_RIGHT \ */ tmp = im->border.top; im->border.top = im->border.right; im->border.right = im->border.bottom; @@ -139,7 +140,7 @@ __imlib_FlipImageDiagonal(ImlibImage * im, int direction) w = -w; hw = hw + 1; break; - case 3: /*\ UP_LEFT \ */ + case 3: /*\ UP_LEFT \ */ tmp = im->border.top; im->border.top = im->border.right; im->border.right = tmp; @@ -1873,7 +1874,7 @@ __imlib_fill_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb, g, b, a, op); } } - + if (dec >= 0) dec += 4 * b2 * (1 - (x--)); dec += a2 * (4 * y + 6); @@ -2076,13 +2077,17 @@ span_clipped(ImlibImage * im, int y, edgeRec * pt1, edgeRec * pt2, ix2 = pt2->x; idx = ix2 - ix1; if (idx == 0) - { return; - } + + /* clip x, y is clipped for us by the caller */ + if (ix1 < clip_xmin) + ix1 = clip_xmin; + if (ix2 > clip_xmax) + ix2 = clip_xmax; + do { - __imlib_draw_set_point_clipped(im, ix1, y, clip_xmin, clip_xmax, - clip_ymin, clip_ymax, r, g, b, a, op); + __imlib_draw_set_point(im, ix1, y, r, g, b, a, op); ix1++; } while (ix1 < ix2); @@ -2090,8 +2095,9 @@ span_clipped(ImlibImage * im, int y, edgeRec * pt1, edgeRec * pt2, void -__imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, DATA8 r, DATA8 g, - DATA8 b, DATA8 a, ImlibOp op) +__imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, int clip_xmin, + int clip_xmax, int clip_ymin, int clip_ymax, + DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op) { long maxy, miny; int iy1, iy2; @@ -2163,99 +2169,171 @@ __imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, DATA8 r, DATA8 g, } } while (pnt1 != iminy); - do + + if (clip_xmin != clip_xmax) { - span(im, iy1, &table1[iy1], &table2[iy1], r, g, b, a, op); - iy1++; + /* there is a cliprect, don't bother with y outside of it */ + if (iy1 < clip_ymin) + iy1 = clip_ymin; + if (iy2 > clip_ymax) + iy2 = clip_ymax; + do + { + span_clipped(im, iy1, &table1[iy1], &table2[iy1], clip_xmin, + clip_xmax, clip_ymin, clip_ymax, r, g, b, a, op); + iy1++; + } + while (iy1 < iy2); } - while (iy1 < iy2); + else + { + do + { + span(im, iy1, &table1[iy1], &table2[iy1], r, g, b, a, op); + iy1++; + } + while (iy1 < iy2); + } + free(table1); free(table2); } -void -__imlib_draw_polygon_filled_clipped(ImlibImage * im, ImlibPoly poly, - int clip_xmin, int clip_xmax, - int clip_ymin, int clip_ymax, DATA8 r, - DATA8 g, DATA8 b, DATA8 a, ImlibOp op) + +unsigned char +__imlib_polygon_contains_point(ImlibPoly poly, int x, int y) { - long maxy, miny; - int iy1, iy2; - int imaxy, iminy; - int pnt1, pnt2; - int i; - edgeRec *table1, *table2; + int count = 0; + int start = 0; + int ysave = 0; /* initial value arbitrary */ + int cx, nx, out_x, out_y, i, n; + int curr_x, curr_y, next_x, next_y; - if (poly->pointcount < 3) - { - return; - } + /* find a vertex of poly that does not lie on the test line */ + while (start < poly->pointcount && poly->points[start].y == y) + start++; + /* if one doesn't exist we will use point on segment test + and can start with vertex 0 anyway */ + cx = start % poly->pointcount; - table1 = malloc(sizeof(edgeRec) * im->h); - table2 = malloc(sizeof(edgeRec) * im->h); + out_x = poly->points[0].x; + out_y = y; - maxy = miny = poly->points[0].y; - imaxy = iminy = 0; for (i = 1; i < poly->pointcount; i++) { - if (poly->points[i].y > maxy) + out_x = MAX(out_x, poly->points[i].x); + } + out_x++; /* out now guaranteed to be outside poly */ + + for (n = 0; n < poly->pointcount; n++) + { + nx = (cx + 1) % poly->pointcount; + + curr_x = poly->points[cx].x; + curr_y = poly->points[cx].y; + next_x = poly->points[nx].x; + next_y = poly->points[nx].y; + + if (__imlib_point_on_segment(x, y, curr_x, curr_y, next_x, next_y)) + return TRUE; + + /* ignore horizontal segments from this point on */ + if (poly->points[cx].y != poly->points[nx].y) { - maxy = poly->points[i].y; - imaxy = i; - } - if (poly->points[i].y < miny) - { - miny = poly->points[i].y; - iminy = i; + if (__imlib_segments_intersect + (curr_x, curr_y, next_x, next_y, x, y, out_x, out_y)) + { + count++; + + if (__imlib_point_on_segment(next_x, next_y, x, y, out_x, out_y)) + { + /* current seg intersects test seg @ 2nd vtx + reset ysave */ + ysave = curr_y; + } + if (__imlib_point_on_segment(curr_x, curr_y, x, y, out_x, out_y) + && (ysave < y != next_y < y)) + { + /* current seg xsects test seg @ 1st vtx and + ysave on opposite side of test line from + curr seg 2nd vtx; + decrement hits (2-1) for odd parity */ + count--; + } + } } + cx = nx; + } + return (count % 2 == 1); +} + +unsigned char +__imlib_point_on_segment(int p_x, int p_y, int s1_x, int s1_y, int s2_x, + int s2_y) +{ + return __imlib_segments_intersect(p_x, p_y, p_x, p_y, s1_x, s1_y, s2_x, + s2_y); +} + +unsigned char +__imlib_segments_intersect(int r1_x, int r1_y, int r2_x, int r2_y, int s1_x, + int s1_y, int s2_x, int s2_y) +{ + double testS1R = + __imlib_point_delta_from_line(s1_x, s1_y, r1_x, r1_y, r2_x, r2_y); + double testS2R = + __imlib_point_delta_from_line(s2_x, s2_y, r1_x, r1_y, r2_x, r2_y); + double testR1S = + __imlib_point_delta_from_line(r1_x, r1_y, s1_x, s1_y, s2_x, s2_y); + double testR2S = + __imlib_point_delta_from_line(r2_x, r2_y, s1_x, s1_y, s2_x, s2_y); + + /* check if segments are collinear */ + if (testS1R == 0.0 && testS2R == 0.0) + { + if (__imlib_point_inside_segment(s1_x, s1_y, r1_x, r1_y, r2_x, r2_y) + || __imlib_point_inside_segment(s2_x, s2_y, r1_x, r1_y, r2_x, r2_y) + || __imlib_point_inside_segment(r1_x, r1_y, s1_x, s1_y, s2_x, s2_y) + || __imlib_point_inside_segment(r2_x, r2_y, s1_x, s1_y, s2_x, s2_y)) + return TRUE; + else + return FALSE; + } + + if (testS1R * testS2R <= 0.0 && testR1S * testR2S <= 0.0) + return TRUE; + else + return FALSE; +} + +/* TODO this could prolly be a macro */ +unsigned char +__imlib_point_inside_segment(int p_x, int p_y, int s1_x, int s1_y, int s2_x, + int s2_y) +{ + /* Check if p lies on segment [ s1, s2 ] given that + it lies on the line defined by s1 and s2. */ + if (s1_y != s2_y) + { + if (p_y <= MAX(s1_y, s2_y) && p_y >= MIN(s1_y, s2_y)) + return TRUE; + } + else if (p_x <= MAX(s1_x, s2_x) && p_x >= MIN(s1_x, s2_x)) + return TRUE; + + return FALSE; +} + +double +__imlib_point_delta_from_line(int p_x, int p_y, int s1_x, int s1_y, int s2_x, + int s2_y) +{ + if (s2_x - s1_x == 0.0) + return p_x - s1_x; + else + { + double m = (double) (s2_y - s1_y) / (double) (s2_x - s1_x); + + return (p_y - s1_y - (double) (p_x - s1_x) * m); } - iy1 = miny; - iy2 = maxy; - if (iy1 == iy2) - { - return; - } - pnt1 = iminy; - pnt2 = iminy + 1; - if (pnt2 >= poly->pointcount) - { - pnt2 = 0; - } - do - { - edge(table1, &poly->points[pnt1], &poly->points[pnt2]); - pnt1 = pnt2; - pnt2 = pnt2 + 1; - if (pnt2 >= poly->pointcount) - { - pnt2 = 0; - } - } - while (pnt1 != imaxy); - pnt1 = imaxy; - pnt2 = imaxy + 1; - if (pnt2 >= poly->pointcount) - { - pnt2 = 0; - } - do - { - edge(table2, &poly->points[pnt1], &poly->points[pnt2]); - pnt1 = pnt2; - pnt2 = pnt2 + 1; - if (pnt2 >= poly->pointcount) - { - pnt2 = 0; - } - } - while (pnt1 != iminy); - do - { - span_clipped(im, iy1, &table1[iy1], &table2[iy1], clip_xmin, clip_xmax, - clip_ymin, clip_ymax, r, g, b, a, op); - iy1++; - } - while (iy1 < iy2); - free(table1); - free(table2); } diff --git a/src/rgbadraw.h b/src/rgbadraw.h index e822fa7..227d797 100644 --- a/src/rgbadraw.h +++ b/src/rgbadraw.h @@ -101,10 +101,7 @@ __imlib_draw_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb, int clip_ymax, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); void -__imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, DATA8 r, DATA8 g, - DATA8 b, DATA8 a, ImlibOp op); -void -__imlib_draw_polygon_filled_clipped(ImlibImage * im, ImlibPoly poly, +__imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, int clip_xmin, int clip_xmax, int clip_ymin, int clip_ymax, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); @@ -116,4 +113,18 @@ __imlib_fill_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb, int clip_xmin, int clip_xmax, int clip_ymin, int clip_ymax, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); +unsigned char +__imlib_polygon_contains_point(ImlibPoly poly, int x, int y); +unsigned char +__imlib_point_on_segment(int p_x, int p_y, int s1_x, int s1_y, int s2_x, + int s2_y); +unsigned char +__imlib_segments_intersect(int r1_x, int r1_y, int r2_x, int r2_y, int s1_x, + int s1_y, int s2_x, int s2_y); +unsigned char +__imlib_point_inside_segment(int p_x, int p_y, int s1_x, int s1_y, int s2_x, + int s2_y); +double +__imlib_point_delta_from_line(int p_x, int p_y, int s1_x, int s1_y, int s2_x, + int s2_y); #endif