ext/rfreeimage/rfi_main.c in rfreeimage-0.2.1 vs ext/rfreeimage/rfi_main.c in rfreeimage-0.2.4

- old
+ new

@@ -23,10 +23,28 @@ *x = *y; *y = tmp; } } +static int min_of_arrary(int x1, int x2, int x3, int x4) +{ + int m = x1; + if(x2 < m) m = x2; + if(x3 < m) m = x3; + if(x4 < m) m = x4; + return m; +} + +static int max_of_arrary(int x1, int x2, int x3, int x4) +{ + int m = x1; + if(x2 > m) m = x2; + if(x3 > m) m = x3; + if(x4 > m) m = x4; + return m; +} + static VALUE rb_rfi_version(VALUE self) { return rb_ary_new3(3, INT2NUM(FREEIMAGE_MAJOR_VERSION), INT2NUM(FREEIMAGE_MINOR_VERSION), INT2NUM(FREEIMAGE_RELEASE_SERIAL)); } @@ -46,10 +64,71 @@ int stride; FREE_IMAGE_FORMAT fif; FIBITMAP *handle; }; +static void dd_line(struct native_image* img, int x0, int y0, + int x1,int y1, + unsigned int bgra, int size) +{ + float x, dx, dy, y, k, deta, threshold=0.0001; + int hs = size / 2, i; + + dx = x1-x0; + dy = y1-y0; + + if(dx < threshold && dx > -threshold){ + k = 0.0; + } + else + { + k=dy * 1.0 / dx; + } + + if(dx > threshold) + { + deta = k > 1 ? 1.0 / k : 1; + for(i = -hs; i <= hs; i++) { + y = y0; + for (x = x0; x <= x1; x += deta){ + FreeImage_SetPixelColor(img->handle, x + i, img->h - (y + i) - 1 , (RGBQUAD*)&bgra); + y = y + k * deta; + } + } + } + else if(dx < -threshold) + { + deta = k > 1 ? 1.0 / k : 1; + for(i = -hs; i <= hs; i++) { + y = y0; + for (x = x0; x >= x1; x -= deta){ + FreeImage_SetPixelColor(img->handle, x + i, img->h - (y + i) - 1, (RGBQUAD*)&bgra); + y = y - k * deta; + } + } + } + else + { + if(dy >= 0) + { + for(i = -hs; i <= hs; i++) { + for (y = y0; y <= y1; y++){ + FreeImage_SetPixelColor(img->handle, x0 + i, img->h - (y + i) - 1, (RGBQUAD*)&bgra); + } + } + } + else + { + for(i = -hs; i <= hs; i++) { + for (y = y0; y >= y1; y--){ + FreeImage_SetPixelColor(img->handle, x0 + i, img->h - (y + i) - 1, (RGBQUAD*)&bgra); + } + } + } + } +} + static void Image_free(struct native_image* img) { if(!img) return; if(img->handle) @@ -671,10 +750,31 @@ } return self; } +static VALUE Image_draw_line(VALUE self, VALUE _x1, VALUE _y1, + VALUE _x2, VALUE _y2, + VALUE color, VALUE _size) +{ + struct native_image* img; + int x1 = NUM2INT(_x1); + int y1 = NUM2INT(_y1); + int x2 = NUM2INT(_x2); + int y2 = NUM2INT(_y2); + int size = NUM2INT(_size); + unsigned int bgra = NUM2UINT(color); + if (size < 0) + rb_raise(rb_eArgError, "Invalid point size: %d", size); + Data_Get_Struct(self, struct native_image, img); + RFI_CHECK_IMG(img); + + dd_line(img, x1, y1, x2, y2, bgra, size); + + return self; +} + static VALUE Image_draw_rectangle(VALUE self, VALUE _x1, VALUE _y1, VALUE _x2, VALUE _y2, VALUE color, VALUE _width) { struct native_image* img; @@ -708,10 +808,44 @@ } return self; } +/* +daw arbitrari quadrangle +four point is given clockwise ordered +*/ +static VALUE Image_draw_quadrangle(VALUE self, VALUE _x1, VALUE _y1, + VALUE _x2, VALUE _y2, + VALUE _x3, VALUE _y3, + VALUE _x4, VALUE _y4, + VALUE color, VALUE _width) +{ + struct native_image* img; + int x1 = NUM2INT(_x1); + int y1 = NUM2INT(_y1); + int x2 = NUM2INT(_x2); + int y2 = NUM2INT(_y2); + int x3 = NUM2INT(_x3); + int y3 = NUM2INT(_y3); + int x4 = NUM2INT(_x4); + int y4 = NUM2INT(_y4); + int size = NUM2INT(_width); + unsigned int bgra = NUM2UINT(color); + if (size < 0) + rb_raise(rb_eArgError, "Invalid line width: %d", size); + Data_Get_Struct(self, struct native_image, img); + RFI_CHECK_IMG(img); + + dd_line(img, x1, y1, x2, y2, bgra, size); + dd_line(img, x2, y2, x3, y3, bgra, size); + dd_line(img, x3, y3, x4, y4, bgra, size); + dd_line(img, x4, y4, x1, y1, bgra, size); + + return self; +} + static VALUE Image_fill_rectangle(VALUE self, VALUE _x1, VALUE _y1, VALUE _x2, VALUE _y2, VALUE color) { struct native_image* img; @@ -735,11 +869,61 @@ } return self; } +/* +daw arbitrari quadrangle +four point is given clockwise ordered +*/ +static VALUE Image_fill_quadrangle(VALUE self, VALUE _x1, VALUE _y1, + VALUE _x2, VALUE _y2, + VALUE _x3, VALUE _y3, + VALUE _x4, VALUE _y4, + VALUE color) +{ + struct native_image* img; + int x1 = NUM2INT(_x1); + int y1 = NUM2INT(_y1); + int x2 = NUM2INT(_x2); + int y2 = NUM2INT(_y2); + int x3 = NUM2INT(_x3); + int y3 = NUM2INT(_y3); + int x4 = NUM2INT(_x4); + int y4 = NUM2INT(_y4); + unsigned int bgra = NUM2UINT(color); + int d1, d2, d3, d4; + int x,y; + int minx, miny, maxx, maxy; + + Data_Get_Struct(self, struct native_image, img); + RFI_CHECK_IMG(img); + + minx = min_of_arrary(x1,x2,x3,x4); + maxx = max_of_arrary(x1,x2,x3,x4); + miny = min_of_arrary(y1,y2,y3,y4); + maxy = max_of_arrary(y1,y2,y3,y4); + + for(x = minx; x <= maxx; x++) { + for(y = miny; y <= maxy; y++) { + //if inner + d1 = (x2 - x1) * (y - y1) - (y2 - y1) * (x - x1); + d2 = (x3 - x2) * (y - y2) - (y3 - y2) * (x - x2); + d3 = (x4 - x3) * (y - y3) - (y4 - y3) * (x - x3); + d4 = (x1 - x4) * (y - y4) - (y1 - y4) * (x - x4); + + if((d1 > 0 && d2 > 0 && d3 >0 && d4 >0) || (d1 < 0 && d2 < 0 && d3 < 0 && d4 <0)) + { + FreeImage_SetPixelColor(img->handle, x, img->h - y, (RGBQUAD*)&bgra); + } + } + } + + return self; +} + void Init_rfreeimage(void) { rb_mFI = rb_define_module("RFreeImage"); rb_define_module_function(rb_mFI, "freeimage_version", rb_rfi_version, 0); rb_define_module_function(rb_mFI, "freeimage_string_version", rb_rfi_string_version, 0); @@ -770,11 +954,14 @@ rb_define_method(Class_Image, "flip_horizontal", Image_flip_horizontal, 0); rb_define_method(Class_Image, "flip_vertical", Image_flip_vertical, 0); /* draw */ rb_define_method(Class_Image, "draw_point", Image_draw_point, 4); + rb_define_method(Class_Image, "draw_line", Image_draw_line, 4 + 2); rb_define_method(Class_Image, "draw_rectangle", Image_draw_rectangle, 4 + 2); + rb_define_method(Class_Image, "draw_quadrangle", Image_draw_quadrangle, 8 + 2); rb_define_method(Class_Image, "fill_rectangle", Image_fill_rectangle, 4 + 1); + rb_define_method(Class_Image, "fill_quadrangle", Image_fill_quadrangle, 8 + 1); rb_define_singleton_method(Class_Image, "ping", Image_ping, 1); rb_define_singleton_method(Class_Image, "from_blob", Image_from_blob, -1); rb_define_singleton_method(Class_Image, "ping_blob", Image_ping_blob, 1); rb_define_singleton_method(Class_Image, "from_bytes", Image_from_bytes, 5);