rexim 3 роки тому
батько
коміт
67c291c887
3 змінених файлів з 67 додано та 1 видалено
  1. 19 1
      olive.c
  2. 48 0
      test.c
  3. BIN
      test/frame_expected.png

+ 19 - 1
olive.c

@@ -186,8 +186,8 @@ OLIVECDEF Olivec_Canvas olivec_canvas(uint32_t *pixels, size_t width, size_t hei
 OLIVECDEF Olivec_Canvas olivec_subcanvas(Olivec_Canvas oc, int x, int y, int w, int h);
 OLIVECDEF void olivec_blend_color(uint32_t *c1, uint32_t c2);
 OLIVECDEF void olivec_fill(Olivec_Canvas oc, uint32_t color);
-// TODO: olivec_frame()
 OLIVECDEF void olivec_rect(Olivec_Canvas oc, int x, int y, int w, int h, uint32_t color);
+OLIVECDEF void olivec_frame(Olivec_Canvas oc, int x, int y, int w, int h, size_t thiccness, uint32_t color);
 OLIVECDEF void olivec_circle(Olivec_Canvas oc, int cx, int cy, int r, uint32_t color);
 // TODO: lines with different thiccness
 OLIVECDEF void olivec_line(Olivec_Canvas oc, int x1, int y1, int x2, int y2, uint32_t color);
@@ -308,6 +308,24 @@ OLIVECDEF void olivec_rect(Olivec_Canvas oc, int x, int y, int w, int h, uint32_
     }
 }
 
+OLIVECDEF void olivec_frame(Olivec_Canvas oc, int x, int y, int w, int h, size_t t, uint32_t color)
+{
+    if (t == 0) return; // Nothing to render
+
+    // Convert the rectangle to 2-points representation
+    int x1 = x;
+    int y1 = y;
+    int x2 = x1 + OLIVEC_SIGN(int, w)*(OLIVEC_ABS(int, w) - 1);
+    if (x1 > x2) OLIVEC_SWAP(int, x1, x2);
+    int y2 = y1 + OLIVEC_SIGN(int, h)*(OLIVEC_ABS(int, h) - 1);
+    if (y1 > y2) OLIVEC_SWAP(int, y1, y2);
+
+    olivec_rect(oc, x1 - t/2, y1 - t/2, (x2 - x1 + 1) + t/2*2, t, color);  // Top
+    olivec_rect(oc, x1 - t/2, y1 - t/2, t, (y2 - y1 + 1) + t/2*2, color);  // Left
+    olivec_rect(oc, x1 - t/2, y2 + t/2, (x2 - x1 + 1) + t/2*2, -t, color); // Bottom
+    olivec_rect(oc, x2 + t/2, y1 - t/2, -t, (y2 - y1 + 1) + t/2*2, color);  // Right
+}
+
 OLIVECDEF void olivec_circle(Olivec_Canvas oc, int cx, int cy, int r, uint32_t color)
 {
     int x1, y1, x2, y2;

+ 48 - 0
test.c

@@ -52,6 +52,7 @@ static void *context_realloc(void *oldp, size_t oldsz, size_t newsz)
 
 #define BACKGROUND_COLOR 0xFF202020
 #define FOREGROUND_COLOR 0xFF2020FF
+#define WHITE_COLOR 0xFFAAAAAA
 #define RED_COLOR 0xFF2020AA
 #define GREEN_COLOR 0xFF20AA20
 #define BLUE_COLOR 0xFFAA2020
@@ -398,6 +399,52 @@ Olivec_Canvas test_line_edge_cases(void)
     return oc;
 }
 
+Olivec_Canvas test_frame(void)
+{
+    size_t width = 128;
+    size_t height = 128;
+    Olivec_Canvas oc = canvas_alloc(width, height);
+    olivec_fill(oc, BACKGROUND_COLOR);
+
+    {
+        size_t w = width/2;
+        size_t h = width/2;
+        olivec_frame(oc, 0, 0, w, h, 1, RED_COLOR);
+    }
+
+    {
+        olivec_frame(oc, width/2, height/2, width, height, 1, GREEN_COLOR);
+    }
+
+    // Odd thiccness
+    {
+        size_t w = width/2;
+        size_t h = width/2;
+        size_t t = 5;
+        olivec_frame(oc, width/2 - w/2, height/2 - h/2, w, h, t, WHITE_COLOR);
+        olivec_frame(oc, width/2 - w/2, height/2 - h/2, w, h, 1, RED_COLOR);
+    }
+
+    // Even thiccness
+    {
+        size_t w = width/4;
+        size_t h = width/4;
+        size_t t = 6;
+        olivec_frame(oc, width/2 - w/2, height/2 - h/2, w, h, t, WHITE_COLOR);
+        olivec_frame(oc, width/2 - w/2, height/2 - h/2, w, h, 1, RED_COLOR);
+    }
+
+    // Zero thiccness
+    {
+        size_t w = width/8;
+        size_t h = width/8;
+        size_t t = 0;
+        olivec_frame(oc, width/2 - w/2, height/2 - h/2, w, h, t, WHITE_COLOR);
+    }
+
+    return oc;
+}
+
 Test_Case test_cases[] = {
     DEFINE_TEST_CASE(fill_rect),
     DEFINE_TEST_CASE(fill_circle),
@@ -410,6 +457,7 @@ Test_Case test_cases[] = {
     DEFINE_TEST_CASE(hello_world_text_rendering),
     DEFINE_TEST_CASE(lines_circle),
     DEFINE_TEST_CASE(line_edge_cases),
+    DEFINE_TEST_CASE(frame),
 };
 #define TEST_CASES_COUNT (sizeof(test_cases)/sizeof(test_cases[0]))
 

BIN
test/frame_expected.png