Mercurial > MadButterfly
annotate src/coord.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 | 164162781a7a |
children | 79e9edf4c00a |
rev | line source |
---|---|
2 | 1 /*! \brief Implement coordination tranform mechanism. |
2 * \file | |
3 * This file implements coordination transforming for containers. | |
4 */ | |
1 | 5 #include <stdio.h> |
6 #include <string.h> | |
5
9c331ec9e210
SVG path is partially supported
Thinker K.F. Li <thinker@branda.to>
parents:
3
diff
changeset
|
7 #include "mb_types.h" |
1 | 8 |
3
164162781a7a
Test cairo with Xlib surface
Thinker K.F. Li <thinker@branda.to>
parents:
2
diff
changeset
|
9 /* To keep possibility of changing type of aix */ |
2 | 10 #define MUL(a, b) ((a) * (b)) |
11 #define ADD(a, b) ((a) + (b)) | |
12 #define DIV(a, b) ((a) / (b)) | |
13 #define SUB(a, b) ((a) - (b)) | |
14 | |
15 static void mul_matrix(co_aix *m1, co_aix *m2, co_aix *dst) { | |
16 dst[0] = ADD(MUL(m1[0], m2[0]), MUL(m1[1], m2[3])); | |
17 dst[1] = ADD(MUL(m1[0], m2[1]), MUL(m1[1], m2[4])); | |
18 dst[2] = ADD(ADD(MUL(m1[0], m2[2]), MUL(m1[1], m2[5])), m1[2]); | |
19 dst[3] = ADD(MUL(m1[3], m2[0]), MUL(m1[4], m2[3])); | |
20 dst[4] = ADD(MUL(m1[3], m2[1]), MUL(m1[4], m2[4])); | |
21 dst[5] = ADD(ADD(MUL(m1[3], m2[2]), MUL(m1[4], m2[5])), m1[5]); | |
1 | 22 } |
23 | |
2 | 24 /*! \brief Compute agrregated transform function. |
25 * | |
26 * Base on parent's aggregated matrix if it is existed, or use transform | |
27 * matrix as aggregated matrix. | |
28 */ | |
1 | 29 static void compute_transform_function(coord_t *visit) { |
30 if(visit->parent) | |
31 mul_matrix(visit->parent->aggr_matrix, | |
32 visit->matrix, visit->aggr_matrix); | |
33 else | |
34 memcpy(visit->aggr_matrix, visit->matrix, sizeof(visit->matrix)); | |
35 } | |
36 | |
37 /*! \brief Update aggregate matrices of elements under a sub-tree. | |
38 * | |
39 * A subtree is specified by the root of it. All elements in the subtree | |
40 * are effected by that changes of matrix of the subtree root. | |
41 */ | |
42 void update_aggr_matrix(coord_t *start) { | |
43 coord_t *visit, *child, *next; | |
44 | |
45 compute_transform_function(start); | |
46 | |
47 visit = start; | |
48 while(visit) { | |
49 child = visit->children; | |
50 while(child) { | |
51 compute_transform_function(child); | |
52 child = child->sibling; | |
53 } | |
54 | |
55 if(visit->children) | |
56 visit = visit->children; | |
57 else if(visit->sibling) | |
58 visit = visit->sibling; | |
59 else { | |
60 next = NULL; | |
61 while(visit->parent && visit->parent != start) { | |
62 visit = visit->parent; | |
63 if(visit->sibling) { | |
64 next = visit->sibling; | |
65 break; | |
66 } | |
67 } | |
68 visit = next; | |
69 } | |
70 } | |
71 } | |
72 | |
73 void coord_init(coord_t *co, coord_t *parent) { | |
74 memset(co, 0, sizeof(coord_t)); | |
75 if(parent) { | |
76 co->parent = parent; | |
77 co->sibling = parent->children; | |
78 parent->children = co; | |
79 } | |
80 co->matrix[0] = 1; | |
81 co->matrix[4] = 1; | |
82 } | |
83 | |
2 | 84 void coord_trans_pos(coord_t *co, co_aix *x, co_aix *y) { |
85 co_aix nx, ny; | |
86 | |
87 nx = ADD(ADD(MUL(co->aggr_matrix[0], *x), | |
88 MUL(co->aggr_matrix[1], *y)), | |
89 co->aggr_matrix[2]); | |
90 ny = ADD(ADD(MUL(co->aggr_matrix[3], *x), | |
91 MUL(co->aggr_matrix[4], *y)), | |
92 co->aggr_matrix[5]); | |
93 *x = nx; | |
94 *y = ny; | |
95 } | |
96 | |
1 | 97 #ifdef UNITTEST |
98 | |
99 #include <CUnit/Basic.h> | |
100 | |
101 void test_update_aggr_matrix(void) { | |
102 coord_t elms[6]; | |
2 | 103 co_aix x, y; |
1 | 104 |
105 coord_init(elms, NULL); | |
106 coord_init(elms + 1, elms); | |
107 coord_init(elms + 2, elms); | |
108 coord_init(elms + 3, elms + 1); | |
109 coord_init(elms + 4, elms + 1); | |
110 coord_init(elms + 5, elms + 2); | |
111 | |
112 /* | 2 -1 0 | | |
113 * | 0 1 0 | | |
114 * | 0 0 1 | | |
115 */ | |
116 elms[0].matrix[0] = 2; | |
117 elms[0].matrix[1] = -1; | |
118 | |
119 /* | 1 3 0 | | |
120 * | 5 1 0 | | |
121 * | 0 0 1 | | |
122 */ | |
123 elms[1].matrix[1] = 3; | |
124 elms[1].matrix[3] = 5; | |
125 | |
126 update_aggr_matrix(elms); | |
127 | |
128 /* | -3 5 0 | | |
129 * | 5 1 0 | | |
130 * | 0 0 1 | | |
131 */ | |
132 CU_ASSERT(elms[3].aggr_matrix[0] == -3); | |
133 CU_ASSERT(elms[3].aggr_matrix[1] == 5); | |
134 CU_ASSERT(elms[3].aggr_matrix[2] == 0); | |
135 CU_ASSERT(elms[3].aggr_matrix[3] == 5); | |
136 CU_ASSERT(elms[3].aggr_matrix[4] == 1); | |
137 CU_ASSERT(elms[3].aggr_matrix[5] == 0); | |
138 | |
139 CU_ASSERT(elms[4].aggr_matrix[0] == -3); | |
140 CU_ASSERT(elms[4].aggr_matrix[1] == 5); | |
141 CU_ASSERT(elms[4].aggr_matrix[2] == 0); | |
142 CU_ASSERT(elms[4].aggr_matrix[3] == 5); | |
143 CU_ASSERT(elms[4].aggr_matrix[4] == 1); | |
144 CU_ASSERT(elms[4].aggr_matrix[5] == 0); | |
145 | |
146 CU_ASSERT(elms[5].aggr_matrix[0] == 2); | |
147 CU_ASSERT(elms[5].aggr_matrix[1] == -1); | |
148 CU_ASSERT(elms[5].aggr_matrix[2] == 0); | |
149 CU_ASSERT(elms[5].aggr_matrix[3] == 0); | |
150 CU_ASSERT(elms[5].aggr_matrix[4] == 1); | |
151 CU_ASSERT(elms[5].aggr_matrix[5] == 0); | |
2 | 152 |
153 x = 50; | |
154 y = 99; | |
155 coord_trans_pos(elms + 5, &x, &y); | |
156 CU_ASSERT(x == 1); | |
157 CU_ASSERT(y == 99); | |
1 | 158 } |
159 | |
160 CU_pSuite get_coord_suite(void) { | |
161 CU_pSuite suite; | |
162 | |
163 suite = CU_add_suite("Suite_coord", NULL, NULL); | |
164 CU_ADD_TEST(suite, test_update_aggr_matrix); | |
165 | |
166 return suite; | |
167 } | |
168 | |
169 #endif |