Просмотр исходного кода

Make olivec_copy() flip the image when necessary

rexim 3 лет назад
Родитель
Сommit
d3527761fd
4 измененных файлов с 20 добавлено и 4 удалено
  1. 4 3
      olive.c
  2. 16 1
      test.c
  3. BIN
      test/copy_flip_expected.png
  4. BIN
      test/copy_out_of_bounds_cut_expected.png

+ 4 - 3
olive.c

@@ -700,15 +700,16 @@ OLIVECDEF void olivec_text(Olivec_Canvas oc, const char *text, int tx, int ty, O
 }
 
 // TODO: bilinear interpolation for olivec_copy
-// TODO: olivec_copy() should flip the image horizontally on negative w and verticallly on negative h
 OLIVECDEF void olivec_copy(Olivec_Canvas src, Olivec_Canvas dst, int x, int y, int w, int h)
 {
     int x1, x2, y1, y2;
     if (olivec_normalize_rect(x, y, w, h, dst.width, dst.height, &x1, &x2, &y1, &y2)) {
+        int xa = x1; if (w < 0) xa = x2;
+        int ya = y1; if (h < 0) ya = y2;
         for (int y = y1; y <= y2; ++y) {
             for (int x = x1; x <= x2; ++x) {
-                size_t nx = (x - x1)*src.width/w;
-                size_t ny = (y - y1)*src.height/h;
+                size_t nx = (x - xa)*((int) src.width)/w;
+                size_t ny = (y - ya)*((int) src.height)/h;
                 olivec_blend_color(&OLIVEC_PIXEL(dst, x, y), OLIVEC_PIXEL(src, nx, ny));
             }
         }

+ 16 - 1
test.c

@@ -476,7 +476,7 @@ Olivec_Canvas test_copy_out_of_bounds_cut(void)
     size_t width = 128;
     size_t height = 128;
     Olivec_Canvas dst = canvas_alloc(width, height);
-    olivec_fill(dst, 0xFF1818FF);
+    olivec_fill(dst, RED_COLOR);
     olivec_copy(
         olivec_canvas(png, png_width, png_height, png_width),
         dst,
@@ -485,6 +485,20 @@ Olivec_Canvas test_copy_out_of_bounds_cut(void)
     return dst;
 }
 
+Olivec_Canvas test_copy_flip(void)
+{
+    size_t width = 128;
+    size_t height = 128;
+    Olivec_Canvas dst = canvas_alloc(width, height);
+    Olivec_Canvas src = olivec_canvas(png, png_width, png_height, png_width);
+    olivec_fill(dst, RED_COLOR);
+    olivec_copy(src, dst, 0, 0, width/2, height/2);
+    olivec_copy(src, dst, width - 1, 0, -width/2, height/2);
+    olivec_copy(src, dst, 0, height - 1, width/2, -height/2);
+    olivec_copy(src, dst, width - 1, height - 1, -width/2, -height/2);
+    return dst;
+}
+
 Test_Case test_cases[] = {
     DEFINE_TEST_CASE(fill_rect),
     DEFINE_TEST_CASE(fill_circle),
@@ -500,6 +514,7 @@ Test_Case test_cases[] = {
     DEFINE_TEST_CASE(frame),
     DEFINE_TEST_CASE(blending_of_copy),
     DEFINE_TEST_CASE(copy_out_of_bounds_cut),
+    DEFINE_TEST_CASE(copy_flip),
 };
 #define TEST_CASES_COUNT (sizeof(test_cases)/sizeof(test_cases[0]))
 

BIN
test/copy_flip_expected.png


BIN
test/copy_out_of_bounds_cut_expected.png