diff src/geo.c @ 5:9c331ec9e210

SVG path is partially supported
author Thinker K.F. Li <thinker@branda.to>
date Sat, 26 Jul 2008 01:37:35 +0800
parents
children 7cfecdce94cc
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/geo.c	Sat Jul 26 01:37:35 2008 +0800
@@ -0,0 +1,154 @@
+/*! \brief Determine who should be re-drawed.
+ * \file
+ * When part of graphic are chagned, not mater size, shape, or position,
+ * the components effected or overlaid should be re-drawed.  This module
+ * figures out components that should be re-drawed.
+ */
+#include <stdio.h>
+#include "mb_types.h"
+
+struct _geo {
+    co_aix x, y;
+    co_aix w, h;
+    co_aix rel_x, rel_y;
+    co_aix orig_x, orig_y;
+    int n_subs;
+    struct _geo *subs;
+};
+
+static int is_pos_in(co_aix x, co_aix y,
+		     co_aix rectx, co_aix recty,
+		     co_aix rectw, co_aix recth) {
+    co_aix rel_x, rel_y;
+
+    rel_x = x - rectx;
+    if(rel_x < 0 || rel_x >= rectw)
+	return 0;
+    rel_y = y - recty;
+    if(rel_y < 0 || rel_y >= recth)
+	return 0;
+    return 1;
+}
+
+static int is_scale_overlay(co_aix x1, co_aix w1, co_aix x2, co_aix w2) {
+    if(x1 > x2) {
+	if((x1 - x2) >= w2)
+	    return 0;
+    } else {
+	if((x2 - x1) >= w1)
+	    return 0;
+    }
+    return 1;
+}
+
+static int is_overlay(geo_t *r1, geo_t *r2) {
+    co_aix rel_x, rel_y;
+
+    if(!is_scale_overlay(r1->x, r1->w, r2->x, r2->w))
+	return 0;
+    if(!is_scale_overlay(r1->y, r1->h, r2->y, r2->h))
+	return 0;
+
+    return 1;
+}
+
+void geo_init(geo_t *g, int n_pos, co_aix pos[][2]) {
+    co_aix min_x, max_x;
+    co_aix min_y, max_y;
+    co_aix x, y;
+    int i;
+
+    min_x = max_x = pos[0][0];
+    min_y = max_y = pos[0][1];
+    for(i = 1; i < n_pos; i++) {
+	x = pos[i][0];
+	if(x < min_x)
+	    min_x = x;
+	else if(x > max_x)
+	    max_x = x;
+	y = pos[i][1];
+	if(y < min_y)
+	    min_y = y;
+	else if(y > max_y)
+	    max_y = y;
+    }
+    g->x = min_x;
+    g->w = max_x - min_x;
+    g->y = min_y;
+    g->h = max_y - min_y;
+}
+
+void geo_mark_overlay(geo_t *g, int n_others, geo_t **others,
+		      int *n_overlays, geo_t **overlays) {
+    int i, ov_idx;
+
+    ov_idx = 0;
+    for(i = 0; i < n_others; i++) {
+	if(is_overlay(g, others[i]))
+	    overlays[ov_idx++] = others[i];
+    }
+    *n_overlays = ov_idx;
+}
+
+
+#ifdef UNITTEST
+
+#include <CUnit/Basic.h>
+
+void test_geo_init(void) {
+    co_aix data[][2] = {
+	{33, 25}, {49, 12},
+	{14, 28}, {39, 56}};
+    geo_t g;
+    
+    geo_init(&g, 4, data);
+    CU_ASSERT(g.x == 14);
+    CU_ASSERT(g.w == 35);
+    CU_ASSERT(g.y == 12);
+    CU_ASSERT(g.h == 44);
+}
+
+void test_geo_mark_overlay(void) {
+    geo_t _geos[3], *geos[3], *overlays[3];
+    geo_t g;
+    int i, n_ov;
+
+    for(i = 0; i < 3; i++) {
+	_geos[i].x = i * 50;
+	_geos[i].y = i * 50;
+	_geos[i].w = 55;
+	_geos[i].h = 66;
+	geos[i] = _geos + i;
+    }
+    g.x = 88;
+    g.y = 79;
+    g.w = 70;
+    g.h = 70;
+
+    /* overlay with geos[1] and geos[2] */
+    geo_mark_overlay(&g, 3, geos, &n_ov, overlays);
+    CU_ASSERT(n_ov == 2);
+    CU_ASSERT(overlays[0] == geos[1]);
+    CU_ASSERT(overlays[1] == geos[2]);
+
+    /* right side of geos[1], and up side of geos[2] */
+    g.x = 105;
+    g.y = 50;
+    g.w = 50;
+    g.h = 51;
+    geo_mark_overlay(&g, 3, geos, &n_ov, overlays);
+    CU_ASSERT(n_ov == 1);
+    CU_ASSERT(overlays[0] == geos[2]);
+}
+
+CU_pSuite get_geo_suite(void) {
+    CU_pSuite suite;
+
+    suite = CU_add_suite("Suite_geo", NULL, NULL);
+    CU_ADD_TEST(suite, test_geo_init);
+    CU_ADD_TEST(suite, test_geo_mark_overlay);
+
+    return suite;
+}
+
+#endif