annotate src/tools.c @ 881:a17c4e231e54 abs_n_rel_center

Transform positions of radient paints. cx, cy of radial and x1, y1, x2, y2 of linear gradient paints must be transformed with aggregated matrix of painted shapes. Pattern to user space transformation maybe used to get more precise color.
author Thinker K.F. Li <thinker@codemud.net>
date Sat, 25 Sep 2010 20:12:45 +0800
parents 586e50f82c1f
children
rev   line source
822
586e50f82c1f Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents: 186
diff changeset
1 // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*-
586e50f82c1f Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents: 186
diff changeset
2 // vim: sw=4:ts=8:sts=4
12
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
3 #include <stdlib.h>
186
530bb7728546 Move header files to $(top_srcdir)/include/ and prefixed with 'mb_'.
Thinker K.F. Li <thinker@branda.to>
parents: 185
diff changeset
4 #include "mb_tools.h"
12
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
5
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
6
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
7 /*! \brief Small fixed size data elements management.
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
8 *
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
9 * It is used to management a large number of data elements
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
10 * they with the same memory size, a fixed size. It allocate
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
11 * a large block for a lot of elements a time for more efficiency
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
12 * utilization of memory.
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
13 *
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
14 * Elements with the size and in a large number usually be accessed
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
15 * very close in time. Allocate a large block for elements also
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
16 * increase cache hit rate.
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
17 *
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
18 * Blocks are keep track as a linking list. They are freed when
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
19 * the elmpool_t is freed. It costs overhead of size of a element
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
20 * for each block. We use memory of first element of blocks to
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
21 * be next pointer of linking list. So, it can not be used by user
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
22 * code.
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
23 */
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
24 struct _elmpool {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
25 int elm_sz;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
26 int inc_num;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
27 void *frees;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
28 void *blks; /* list of allocated blocks. */
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
29 };
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
30
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
31 /*! \brief Create a new data elements pool.
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
32 *
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
33 * elmpool_t provide a pool of fixed size elements to gain better
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
34 * utilization of memory. It try to allocate bigger memory blocks
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
35 * for multiple elements.
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
36 *
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
37 * \param elm_sz size of elements.
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
38 * \param inc_num is number of elments to allocate every time. (>= 16)
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
39 * \return A elmpool or NULL for error.
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
40 */
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
41 elmpool_t *elmpool_new(int elm_sz, int inc_num) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
42 int _elm_sz;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
43 elmpool_t *pool;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
44
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
45 if(inc_num < 16)
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
46 return NULL;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
47
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
48 if(elm_sz >= sizeof(void *))
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
49 _elm_sz = elm_sz;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
50 else
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
51 _elm_sz = sizeof(void *);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
52
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
53 pool = (elmpool_t *)malloc(sizeof(elmpool_t));
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
54 if(pool == NULL)
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
55 return NULL;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
56
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
57 pool->elm_sz = _elm_sz;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
58 if(inc_num == 0)
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
59 inc_num = 256;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
60 pool->inc_num = inc_num;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
61 pool->frees = NULL;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
62 pool->blks = NULL;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
63
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
64 return pool;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
65 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
66
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
67 void *elmpool_elm_alloc(elmpool_t *pool) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
68 void *blk, *elm;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
69 int elm_sz, inc_num;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
70 int i;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
71
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
72 if(pool->frees == NULL) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
73 inc_num = pool->inc_num;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
74 elm_sz = pool->elm_sz;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
75 blk = malloc(elm_sz * inc_num);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
76 if(blk == NULL)
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
77 return NULL;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
78
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
79 *(void **)blk = pool->blks;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
80 pool->blks = blk;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
81
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
82 blk = blk + elm_sz;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
83 pool->frees = blk;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
84 for(i = 2; i < inc_num; i++) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
85 *(void **)blk = blk + elm_sz;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
86 blk = *(void **)blk;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
87 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
88 *(void **)blk = NULL;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
89 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
90
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
91 elm = pool->frees;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
92 pool->frees = *(void **)elm;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
93
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
94 return elm;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
95 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
96
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
97 void elmpool_elm_free(elmpool_t *pool, void *elm) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
98 *(void **)elm = pool->frees;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
99 pool->frees = elm;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
100 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
101
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
102 void elmpool_free(elmpool_t *pool) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
103 void *blk, *next_blk;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
104
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
105 blk = pool->blks;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
106 while(blk) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
107 next_blk = *(void **)blk;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
108 free(blk);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
109 blk = next_blk;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
110 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
111 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
112
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
113 #ifdef UNITTEST
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
114
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
115 #include <CUnit/Basic.h>
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
116
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
117 void test_elmpool(void) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
118 elmpool_t *pool;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
119 void *elm;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
120 int i;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
121
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
122 pool = elmpool_new(64, 16);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
123 for(i = 0; i < 15; i++) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
124 elm = elmpool_elm_alloc(pool);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
125 CU_ASSERT(elm != NULL);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
126 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
127 CU_ASSERT(pool->frees == NULL);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
128
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
129 for(i = 0; i < 15; i++) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
130 elm = elmpool_elm_alloc(pool);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
131 CU_ASSERT(elm != NULL);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
132 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
133 CU_ASSERT(pool->frees == NULL);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
134
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
135 elmpool_elm_free(pool, elm);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
136 CU_ASSERT(pool->frees == elm);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
137
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
138 elm = elmpool_elm_alloc(pool);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
139 CU_ASSERT(elm != NULL);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
140 CU_ASSERT(pool->frees == NULL);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
141
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
142 elmpool_free(pool);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
143 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
144
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
145 CU_pSuite get_tools_suite(void) {
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
146 CU_pSuite suite;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
147
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
148 suite = CU_add_suite("Suite_tools", NULL, NULL);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
149 CU_ADD_TEST(suite, test_elmpool);
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
150
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
151 return suite;
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
152 }
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
153
79e9edf4c00a Add redraw manager
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
154 #endif /* UNITTEST */