Mercurial > MadButterfly
comparison src/shape_path.c @ 458:bb4f651090bf
Use cairo to transform and draw arc.
- We move some values into float_args.
- fix_args is removed.
- args is rename to pnts.
- We still need to add corner points to pnts at sh_path_arc_cmd_arg_fill().
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Thu, 10 Sep 2009 17:36:45 +0800 |
parents | 16116d84bc5e |
children | 8b155b77fa14 |
comparison
equal
deleted
inserted
replaced
457:ea09fdab333a | 458:bb4f651090bf |
---|---|
17 * it is assigned. | 17 * it is assigned. |
18 */ | 18 */ |
19 typedef struct _sh_path { | 19 typedef struct _sh_path { |
20 shape_t shape; | 20 shape_t shape; |
21 int cmd_len; | 21 int cmd_len; |
22 int arg_len; | 22 int pnt_len; |
23 int fix_arg_len; | 23 int float_arg_len; |
24 char *user_data; | 24 char *user_data; |
25 char *dev_data; /* device space data */ | 25 char *dev_data; /* device space data */ |
26 } sh_path_t; | 26 } sh_path_t; |
27 #define RESERVED_AIXS sizeof(co_aix[2]) | 27 #define RESERVED_AIXS sizeof(co_aix[2]) |
28 | 28 |
38 *(x) == '.')) { \ | 38 *(x) == '.')) { \ |
39 (x)++; \ | 39 (x)++; \ |
40 } | 40 } |
41 #define OK 0 | 41 #define OK 0 |
42 #define ERR -1 | 42 #define ERR -1 |
43 #define PI 3.1415926 | 43 #define PI 3.1415926535897931 |
44 | 44 |
45 #ifdef UNITTEST | 45 #ifdef UNITTEST |
46 #undef rdman_shape_man | 46 #undef rdman_shape_man |
47 #define rdman_shape_man(x, y) | 47 #define rdman_shape_man(x, y) |
48 #endif | 48 #endif |
91 * - cx = rx * ucx | 91 * - cx = rx * ucx |
92 * - cx = rx * (udcx + umx) | 92 * - cx = rx * (udcx + umx) |
93 * - cy = ry * ucy | 93 * - cy = ry * ucy |
94 * - cy = ry * (udcy + umy) | 94 * - cy = ry * (udcy + umy) |
95 */ | 95 */ |
96 static int calc_center_and_x_aix(co_aix x0, co_aix y0, | 96 static int _calc_center(co_aix x0, co_aix y0, |
97 co_aix x, co_aix y, | 97 co_aix x, co_aix y, |
98 co_aix rx, co_aix ry, | 98 co_aix rx, co_aix ry, |
99 co_aix x_rotate, | 99 co_aix x_rotate, |
100 int large, int sweep, | 100 int large, int sweep, |
101 co_aix *cx, co_aix *cy, | 101 co_aix *cx, co_aix *cy) { |
102 co_aix *xx, co_aix *xy) { | |
103 co_aix nrx, nry, nrx0, nry0; | 102 co_aix nrx, nry, nrx0, nry0; |
104 co_aix udx, udy, udx2, udy2; | 103 co_aix udx, udy, udx2, udy2; |
105 co_aix umx, umy; | 104 co_aix umx, umy; |
106 co_aix udcx, udcy; | 105 co_aix udcx, udcy; |
107 co_aix nrcx, nrcy; | 106 co_aix nrcx, nrcy; |
108 co_aix udl2; | 107 co_aix udl2; |
109 float _sin = sinf(x_rotate); | 108 float _sin = sinf(x_rotate); |
110 float _cos = cosf(x_rotate); | 109 float _cos = cosf(x_rotate); |
111 int reflect; | 110 int reflect; |
112 | 111 |
112 /* Compute center of the ellipse */ | |
113 nrx = x * _cos + y * _sin; | 113 nrx = x * _cos + y * _sin; |
114 nry = x * -_sin + y * _cos; | 114 nry = x * -_sin + y * _cos; |
115 nrx0 = x0 * _cos + y0 * _sin; | 115 nrx0 = x0 * _cos + y0 * _sin; |
116 nry0 = x0 * -_sin + y0 * _cos; | 116 nry0 = x0 * -_sin + y0 * _cos; |
117 | 117 |
148 nrcy = ry * (udcy + umy); | 148 nrcy = ry * (udcy + umy); |
149 | 149 |
150 *cx = nrcx * _cos - nrcy * _sin; | 150 *cx = nrcx * _cos - nrcy * _sin; |
151 *cy = nrcx * _sin + nrcy * _cos; | 151 *cy = nrcx * _sin + nrcy * _cos; |
152 | 152 |
153 *xx = rx * _cos + *cx; | |
154 *xy = rx * _sin + *cy; | |
155 | |
156 return OK; | 153 return OK; |
157 } | 154 } |
158 | 155 |
156 | |
157 static co_aix _angle_rotated_ellipse(co_aix x, co_aix y, | |
158 co_aix rx, co_aix ry, | |
159 co_aix x_rotate) { | |
160 co_aix nrx, nry; | |
161 co_aix _sin, _cos; | |
162 co_aix xy_tan; | |
163 co_aix angle; | |
164 | |
165 _sin = sinf(x_rotate); | |
166 _cos = cosf(x_rotate); | |
167 | |
168 nrx = (x * _cos + y * _sin) / rx; | |
169 nry = (-x * _sin + y * _cos) / ry; | |
170 xy_tan = nry / nrx; | |
171 | |
172 angle = atan(xy_tan); | |
173 | |
174 if(nrx < 0) | |
175 angle = PI + angle; | |
176 | |
177 return angle; | |
178 } | |
159 | 179 |
160 #define TAKE_NUM(r) do { \ | 180 #define TAKE_NUM(r) do { \ |
161 SKIP_SPACE(p); \ | 181 SKIP_SPACE(p); \ |
162 old = p; \ | 182 old = p; \ |
163 SKIP_NUM(p); \ | 183 SKIP_NUM(p); \ |
166 r = atof(old); \ | 186 r = atof(old); \ |
167 } while(0); | 187 } while(0); |
168 | 188 |
169 static int sh_path_arc_cmd_arg_fill(char cmd, char **cmds_p, | 189 static int sh_path_arc_cmd_arg_fill(char cmd, char **cmds_p, |
170 const char **data_p, | 190 const char **data_p, |
171 co_aix **args_p, | 191 co_aix **pnts_p, |
172 int **fix_args_p) { | 192 co_aix **float_args_p) { |
173 co_aix rx, ry; | 193 co_aix rx, ry; |
174 co_aix x_rotate; | 194 co_aix x_rotate; |
175 int large, sweep; | 195 int large, sweep; |
176 co_aix x, y, x0, y0, cx, cy, xx, xy; | 196 co_aix x, y, x0, y0, cx, cy; |
177 co_aix *args = *args_p; | 197 co_aix angle_start, angle_stop; |
198 co_aix *pnts = *pnts_p; | |
178 const char *old; | 199 const char *old; |
179 const char *p; | 200 const char *p; |
180 char *cmds; | 201 char *cmds; |
181 int *fix_args; | 202 co_aix *float_args; |
182 | 203 |
183 p = *data_p; | 204 p = *data_p; |
184 cmds = *cmds_p; | 205 cmds = *cmds_p; |
185 fix_args = *fix_args_p; | 206 float_args = *float_args_p; |
186 while(*p) { | 207 while(*p) { |
187 SKIP_SPACE(p); | 208 SKIP_SPACE(p); |
188 old = p; | 209 old = p; |
189 SKIP_NUM(p); | 210 SKIP_NUM(p); |
190 if(p == old) | 211 if(p == old) |
196 TAKE_NUM(large); | 217 TAKE_NUM(large); |
197 TAKE_NUM(sweep); | 218 TAKE_NUM(sweep); |
198 TAKE_NUM(x); | 219 TAKE_NUM(x); |
199 TAKE_NUM(y) | 220 TAKE_NUM(y) |
200 | 221 |
201 x0 = *(args - 2); | 222 x0 = *(pnts - 2); |
202 y0 = *(args - 1); | 223 y0 = *(pnts - 1); |
203 | 224 |
204 if(islower(cmd)) { | 225 if(islower(cmd)) { |
205 x += x0; | 226 x += x0; |
206 y += y0; | 227 y += y0; |
207 } | 228 } |
208 | 229 |
209 calc_center_and_x_aix(x0, y0, x, y, | 230 _calc_center(x0, y0, x, y, rx, ry, x_rotate, large, |
210 rx, ry, | 231 sweep, &cx, &cy); |
211 x_rotate, large, sweep, | 232 pnts += 8; /*!< \note Add corners here. */ |
212 &cx, &cy, &xx, &xy); | 233 *(pnts++) = x; |
213 | 234 *(pnts++) = y; |
214 *(args++) = cx; | 235 |
215 *(args++) = cy; | 236 angle_start = _angle_rotated_ellipse(x0 - cx, y0 - cy, |
216 *(args++) = xx; | 237 rx, ry, x_rotate); |
217 *(args++) = xy; | 238 angle_stop = _angle_rotated_ellipse(x - cx, y - cy, |
218 *(args++) = x; | 239 rx, ry, x_rotate); |
219 *(args++) = y; | 240 |
220 | 241 if(sweep && angle_start > angle_stop) |
242 angle_stop += 2 * PI; | |
243 else if((!sweep) && angle_start < angle_stop) | |
244 angle_start += 2 * PI; | |
245 | |
246 *float_args++ = cx; | |
247 *float_args++ = cy; | |
248 *float_args++ = rx; | |
249 *float_args++ = ry; | |
250 *float_args++ = angle_start; | |
251 *float_args++ = angle_stop; | |
252 *float_args++ = x_rotate; | |
253 | |
221 *cmds++ = toupper(cmd); | 254 *cmds++ = toupper(cmd); |
222 *fix_args++ = sweep; | |
223 } | 255 } |
224 | 256 |
225 *data_p = p; | 257 *data_p = p; |
226 *args_p = args; | 258 *pnts_p = pnts; |
227 *cmds_p = cmds; | 259 *cmds_p = cmds; |
228 *fix_args_p = fix_args; | 260 *float_args_p = float_args; |
229 | 261 |
230 return OK; | 262 return OK; |
231 } | 263 } |
232 | 264 |
233 #define INNER(x1, y1, x2, y2) ((x1) * (x2) + (y1) * (y2)) | 265 #define INNER(x1, y1, x2, y2) ((x1) * (x2) + (y1) * (y2)) |
234 #define CROSS(x1, y1, x2, y2) ((x1) * (y2) - (y1) * (x2)) | 266 #define CROSS(x1, y1, x2, y2) ((x1) * (y2) - (y1) * (x2)) |
235 | 267 |
268 static co_aix distance_pow2(co_aix x, co_aix y) { | |
269 return x * x + y * y; | |
270 } | |
271 | |
272 static co_aix angle_diff(co_aix sx, co_aix sy, co_aix dx, co_aix dy) { | |
273 co_aix inner, cross; | |
274 co_aix angle; | |
275 co_aix rd2, rd; | |
276 | |
277 rd2 = distance_pow2(dx, dy); | |
278 rd = sqrtf(rd2); | |
279 | |
280 inner = INNER(sx, sy, dx, dy); | |
281 cross = CROSS(sx, sy, dx, dy); | |
282 angle = acos(inner / rd); | |
283 if(cross < 0) | |
284 angle = 2 * PI - angle; | |
285 | |
286 return angle; | |
287 } | |
288 | |
236 /*! \brief Make path for arcs in a path. | 289 /*! \brief Make path for arcs in a path. |
237 */ | 290 */ |
238 void sh_path_arc_path(mbe_t *cr, const co_aix **args_p, | 291 void _sh_path_arc_path(mbe_t *cr, sh_path_t *path, const co_aix **pnts_p, |
292 const co_aix **float_args_p) { | |
293 co_aix cx, cy, x0, y0, x, y; | |
294 co_aix rx, ry; | |
295 co_aix xyratio; | |
296 co_aix angle_start, angle_stop; | |
297 co_aix x_rotate; | |
298 const co_aix *pnts; | |
299 const co_aix *float_args; | |
300 co_aix matrix[6]; | |
301 co_aix dev_matrix[6]; | |
302 co_aix *aggr; | |
303 co_aix _sin, _cos; | |
304 | |
305 pnts = *pnts_p; | |
306 float_args = *float_args_p; | |
307 x0 = *(pnts - 2); | |
308 y0 = *(pnts - 1); | |
309 pnts += 8; | |
310 x = *pnts++; | |
311 y = *pnts++; | |
312 | |
313 cx = *float_args++; | |
314 cy = *float_args++; | |
315 rx = *float_args++; | |
316 ry = *float_args++; | |
317 angle_start = *float_args++; | |
318 angle_stop = *float_args++; | |
319 x_rotate = *float_args++; | |
320 | |
321 _sin = sinf(x_rotate); | |
322 _cos = cosf(x_rotate); | |
323 | |
324 xyratio = ry / rx; | |
325 aggr = sh_get_aggr_matrix((shape_t *)path); | |
326 matrix[0] = _cos; | |
327 matrix[1] = -_sin * xyratio; | |
328 matrix[2] = cx; | |
329 matrix[3] = _sin; | |
330 matrix[4] = _cos * xyratio; | |
331 matrix[5] = cy; | |
332 | |
333 matrix_mul(aggr, matrix, dev_matrix); | |
334 mbe_save(cr); | |
335 mbe_transform(cr, dev_matrix); | |
336 mbe_arc(cr, 0, 0, rx, angle_start, angle_stop); | |
337 mbe_restore(cr); | |
338 | |
339 *pnts_p = pnts; | |
340 *float_args_p = float_args; | |
341 } | |
342 | |
343 #if 0 | |
344 void __sh_path_arc_path(mbe_t *cr, const co_aix **args_p, | |
239 const int **fix_args_p) { | 345 const int **fix_args_p) { |
240 co_aix cx, cy, x0, y0, x, y, xx, xy; | 346 co_aix cx, cy, x0, y0, x, y; |
241 co_aix dx, dy, dx0, dy0, dxx, dxy; | 347 co_aix dx, dy, dx0, dy0; |
348 co_aix udxx, udxy; | |
242 co_aix xyratio; | 349 co_aix xyratio; |
243 co_aix rx; | 350 co_aix rx; |
244 co_aix rx2; | 351 co_aix rx2; |
352 co_aix dra45x, dra45y, udra45x, udra45y; | |
353 co_aix rra45, rra45_2; | |
245 co_aix inner0, cross0; | 354 co_aix inner0, cross0; |
246 co_aix circle_h0; | |
247 co_aix inner, cross; | 355 co_aix inner, cross; |
248 co_aix angle, angle0; | 356 co_aix angle, angle0; |
249 co_aix rotate; | 357 co_aix rotate; |
358 co_aix _sqrt2; | |
250 const co_aix *args = *args_p; | 359 const co_aix *args = *args_p; |
251 const int *fix_args = *fix_args_p; | 360 const int *fix_args = *fix_args_p; |
252 int sweep; | 361 int sweep; |
362 | |
363 _sqrt2 = sqrtf(2); | |
253 | 364 |
254 x0 = *(args - 2); | 365 x0 = *(args - 2); |
255 y0 = *(args - 1); | 366 y0 = *(args - 1); |
256 cx = *args++; | 367 cx = *args++; |
257 cy = *args++; | 368 cy = *args++; |
258 xx = *args++; | 369 ra45x = *args++; |
259 xy = *args++; | 370 ra45y = *args++; |
260 x = *args++; | 371 x = *args++; |
261 y = *args++; | 372 y = *args++; |
262 sweep = *fix_args++; | 373 sweep = *fix_args++; |
263 | 374 |
264 dx = x - cx; | 375 dx = x - cx; |
265 dy = y - cy; | 376 dy = y - cy; |
266 dx0 = x0 - cx; | 377 dx0 = x0 - cx; |
267 dy0 = y0 - cy; | 378 dy0 = y0 - cy; |
268 dxx = xx - cx; | 379 dra45x = ra45x - cx; |
269 dxy = xy - cy; | 380 dra45y = ra45y - cy; |
270 | 381 |
271 rx2 = dxx * dxx + dxy * dxy; | 382 rra45_2 = dra45x * dra45x + dra45y * dra45y; |
272 rx = sqrtf(rx2); | 383 rra45 = sqrtf(rra45_2); |
384 udra45x = dra45x / rra45; | |
385 udra45y = dra45y / rra45; | |
386 | |
387 udxx = (udra45x + udra45y) * _sqrt2; | |
388 udxy = (-udra45x + udra45y) * _sqrt2; | |
273 | 389 |
274 /*! \note Why we calculate these numbers there? | 390 /*! \note Why we calculate these numbers there? |
275 * If we compute it when filling arguments, sh_path_arc_cmd_arg_fill(), | 391 * If we compute it when filling arguments, sh_path_arc_cmd_arg_fill(), |
276 * we can avoid to recompute it for every drawing. But, transforming of | 392 * we can avoid to recompute it for every drawing. But, transforming of |
277 * coordinate can effect value of the numbers. | 393 * coordinate can effect value of the numbers. |
278 */ | 394 */ |
279 inner0 = INNER(dxx, dxy, dx0, dy0); | 395 rotate = acos(udxx); |
280 cross0 = CROSS(dxx, dxy, dx0, dy0); | 396 if(udxy < 0) |
281 circle_h0 = sqrtf(rx2 - inner0 * inner0 / rx2); | 397 rotate = 2 * PI - rotate; |
282 xyratio = cross0 / rx / circle_h0; | 398 |
399 angle0 = angle_diff(udxx, udxy, dx0, dy0); | |
400 angle = angle_diff(udxx, udxy, dx, dy); | |
401 | |
402 ASSERT(rx != 0); | |
403 xyratio = udra45y / udra45x; | |
283 if(xyratio < 0) | 404 if(xyratio < 0) |
284 xyratio = -xyratio; | 405 xyratio = -xyratio; |
285 | 406 |
286 angle0 = acos(inner0 / rx2); | |
287 if(cross0 < 0) | |
288 angle0 = PI * 2 - angle0; /* 3rd, 4th Quadrant */ | |
289 | |
290 inner = INNER(dxx, dxy, dx, dy); | |
291 cross = CROSS(dxx, dxy, dx, dy); | |
292 angle = acos(inner / rx2); | |
293 if(cross < 0) | |
294 angle = PI * 2 - angle; /* 3rd, 4th Quadrant */ | |
295 | |
296 /* Make a path for arc */ | 407 /* Make a path for arc */ |
297 rotate = acos(dxx / rx); | |
298 mbe_save(cr); | 408 mbe_save(cr); |
299 mbe_translate(cr, cx, cy); | 409 mbe_translate(cr, cx, cy); |
300 mbe_rotate(cr, rotate); | 410 mbe_rotate(cr, rotate); |
301 mbe_scale(cr, 1.0, xyratio); | 411 mbe_scale(cr, 1.0, xyratio); |
302 if(sweep) | 412 if(sweep) |
306 mbe_restore(cr); | 416 mbe_restore(cr); |
307 | 417 |
308 *args_p = args; | 418 *args_p = args; |
309 *fix_args_p = fix_args; | 419 *fix_args_p = fix_args; |
310 } | 420 } |
421 #endif | |
311 | 422 |
312 /* ============================================================ */ | 423 /* ============================================================ */ |
313 | 424 |
314 static void sh_path_free(shape_t *shape) { | 425 static void sh_path_free(shape_t *shape) { |
315 sh_path_t *path = (sh_path_t *)shape; | 426 sh_path_t *path = (sh_path_t *)shape; |
320 | 431 |
321 /*! \brief Count number of arguments. | 432 /*! \brief Count number of arguments. |
322 * | 433 * |
323 * \todo Notify programmers that syntax or value error of path data. | 434 * \todo Notify programmers that syntax or value error of path data. |
324 */ | 435 */ |
325 static int sh_path_cmd_arg_cnt(char *data, int *cmd_cntp, int *arg_cntp, | 436 static int sh_path_cmd_arg_cnt(char *data, int *cmd_cntp, int *pnt_cntp, |
326 int *fix_arg_cntp) { | 437 int *float_arg_cntp) { |
327 char *p, *old; | 438 char *p, *old; |
328 int cmd_cnt, arg_cnt, fix_arg_cnt; | 439 int cmd_cnt, pnt_cnt, float_arg_cnt; |
329 int i; | 440 int i; |
330 | 441 |
331 cmd_cnt = arg_cnt = fix_arg_cnt = 0; | 442 cmd_cnt = pnt_cnt = float_arg_cnt = 0; |
332 p = data; | 443 p = data; |
333 SKIP_SPACE(p); | 444 SKIP_SPACE(p); |
334 while(*p) { | 445 while(*p) { |
335 switch(*p++) { | 446 switch(*p++) { |
336 case 'c': | 447 case 'c': |
340 SKIP_SPACE(p); | 451 SKIP_SPACE(p); |
341 old = p; | 452 old = p; |
342 SKIP_NUM(p); | 453 SKIP_NUM(p); |
343 if(p == old) | 454 if(p == old) |
344 break; | 455 break; |
345 arg_cnt++; | 456 pnt_cnt++; |
346 | 457 |
347 SKIP_SPACE(p); | 458 SKIP_SPACE(p); |
348 old = p; | 459 old = p; |
349 SKIP_NUM(p); | 460 SKIP_NUM(p); |
350 if(p == old) | 461 if(p == old) |
351 return ERR; | 462 return ERR; |
352 arg_cnt++; | 463 pnt_cnt++; |
353 | 464 |
354 SKIP_SPACE(p); | 465 SKIP_SPACE(p); |
355 old = p; | 466 old = p; |
356 SKIP_NUM(p); | 467 SKIP_NUM(p); |
357 if(p == old) | 468 if(p == old) |
358 return ERR; | 469 return ERR; |
359 arg_cnt++; | 470 pnt_cnt++; |
360 | 471 |
361 SKIP_SPACE(p); | 472 SKIP_SPACE(p); |
362 old = p; | 473 old = p; |
363 SKIP_NUM(p); | 474 SKIP_NUM(p); |
364 if(p == old) | 475 if(p == old) |
365 return ERR; | 476 return ERR; |
366 arg_cnt++; | 477 pnt_cnt++; |
367 SKIP_SPACE(p); | 478 SKIP_SPACE(p); |
368 old = p; | 479 old = p; |
369 SKIP_NUM(p); | 480 SKIP_NUM(p); |
370 if(p == old) | 481 if(p == old) |
371 return ERR; | 482 return ERR; |
372 arg_cnt++; | 483 pnt_cnt++; |
373 | 484 |
374 SKIP_SPACE(p); | 485 SKIP_SPACE(p); |
375 old = p; | 486 old = p; |
376 SKIP_NUM(p); | 487 SKIP_NUM(p); |
377 if(p == old) | 488 if(p == old) |
378 return ERR; | 489 return ERR; |
379 arg_cnt++; | 490 pnt_cnt++; |
380 | 491 |
381 cmd_cnt++; | 492 cmd_cnt++; |
382 } | 493 } |
383 break; | 494 break; |
384 case 's': | 495 case 's': |
390 SKIP_SPACE(p); | 501 SKIP_SPACE(p); |
391 old = p; | 502 old = p; |
392 SKIP_NUM(p); | 503 SKIP_NUM(p); |
393 if(p == old) | 504 if(p == old) |
394 break; | 505 break; |
395 arg_cnt++; | 506 pnt_cnt++; |
396 | 507 |
397 SKIP_SPACE(p); | 508 SKIP_SPACE(p); |
398 old = p; | 509 old = p; |
399 SKIP_NUM(p); | 510 SKIP_NUM(p); |
400 if(p == old) | 511 if(p == old) |
401 return ERR; | 512 return ERR; |
402 arg_cnt++; | 513 pnt_cnt++; |
403 | 514 |
404 SKIP_SPACE(p); | 515 SKIP_SPACE(p); |
405 old = p; | 516 old = p; |
406 SKIP_NUM(p); | 517 SKIP_NUM(p); |
407 if(p == old) | 518 if(p == old) |
408 return ERR; | 519 return ERR; |
409 arg_cnt++; | 520 pnt_cnt++; |
410 | 521 |
411 SKIP_SPACE(p); | 522 SKIP_SPACE(p); |
412 old = p; | 523 old = p; |
413 SKIP_NUM(p); | 524 SKIP_NUM(p); |
414 if(p == old) | 525 if(p == old) |
415 return ERR; | 526 return ERR; |
416 arg_cnt++; | 527 pnt_cnt++; |
417 | 528 |
418 cmd_cnt++; | 529 cmd_cnt++; |
419 } | 530 } |
420 break; | 531 break; |
421 case 'm': | 532 case 'm': |
429 SKIP_SPACE(p); | 540 SKIP_SPACE(p); |
430 old = p; | 541 old = p; |
431 SKIP_NUM(p); | 542 SKIP_NUM(p); |
432 if(p == old) | 543 if(p == old) |
433 break; | 544 break; |
434 arg_cnt++; | 545 pnt_cnt++; |
435 | 546 |
436 SKIP_SPACE(p); | 547 SKIP_SPACE(p); |
437 old = p; | 548 old = p; |
438 SKIP_NUM(p); | 549 SKIP_NUM(p); |
439 if(p == old) | 550 if(p == old) |
440 return ERR; | 551 return ERR; |
441 arg_cnt++; | 552 pnt_cnt++; |
442 | 553 |
443 cmd_cnt++; | 554 cmd_cnt++; |
444 } | 555 } |
445 break; | 556 break; |
446 case 'h': | 557 case 'h': |
451 SKIP_SPACE(p); | 562 SKIP_SPACE(p); |
452 old = p; | 563 old = p; |
453 SKIP_NUM(p); | 564 SKIP_NUM(p); |
454 if(p == old) | 565 if(p == old) |
455 break; | 566 break; |
456 arg_cnt += 2; | 567 pnt_cnt += 2; |
457 | 568 |
458 cmd_cnt++; | 569 cmd_cnt++; |
459 } | 570 } |
460 break; | 571 break; |
461 case 'A': | 572 case 'A': |
473 SKIP_NUM(p); | 584 SKIP_NUM(p); |
474 if(p == old) | 585 if(p == old) |
475 return ERR; | 586 return ERR; |
476 } | 587 } |
477 | 588 |
478 arg_cnt += 6; | 589 pnt_cnt += 10; |
479 fix_arg_cnt++; | 590 float_arg_cnt += 7; |
480 | 591 |
481 cmd_cnt++; | 592 cmd_cnt++; |
482 } | 593 } |
483 break; | 594 break; |
484 case 'z': | 595 case 'z': |
491 /*! \todo cmd_cnt should be increased for each implicit repeating. */ | 602 /*! \todo cmd_cnt should be increased for each implicit repeating. */ |
492 SKIP_SPACE(p); | 603 SKIP_SPACE(p); |
493 } | 604 } |
494 | 605 |
495 *cmd_cntp = cmd_cnt; | 606 *cmd_cntp = cmd_cnt; |
496 *arg_cntp = arg_cnt; | 607 *pnt_cntp = pnt_cnt; |
497 *fix_arg_cntp = fix_arg_cnt; | 608 *float_arg_cntp = float_arg_cnt; |
498 return OK; | 609 return OK; |
499 } | 610 } |
500 | 611 |
501 #define TO_ABSX islower(cmd)? x + atof(old): atof(old) | 612 #define TO_ABSX islower(cmd)? x + atof(old): atof(old) |
502 #define TO_ABSY islower(cmd)? y + atof(old): atof(old) | 613 #define TO_ABSY islower(cmd)? y + atof(old): atof(old) |
503 | 614 |
504 static int sh_path_cmd_arg_fill(char *data, sh_path_t *path) { | 615 static int sh_path_cmd_arg_fill(char *data, sh_path_t *path) { |
505 char *p, *old; | 616 char *p, *old; |
506 char *cmds; | 617 char *cmds; |
507 char cmd; | 618 char cmd; |
508 co_aix *args; | 619 co_aix *pnts; |
509 int *fix_args; | 620 co_aix *float_args; |
510 co_aix x, y; | 621 co_aix x, y; |
511 int r; | 622 int r; |
512 | 623 |
513 cmds = path->user_data; | 624 cmds = path->user_data; |
514 args = (co_aix *)(cmds + path->cmd_len); | 625 pnts = (co_aix *)(cmds + path->cmd_len); |
515 fix_args = (int *)(cmds + path->cmd_len + | 626 float_args = (co_aix *)(cmds + path->cmd_len + |
516 path->arg_len * sizeof(co_aix)); | 627 path->pnt_len * sizeof(co_aix)); |
517 p = data; | 628 p = data; |
518 SKIP_SPACE(p); | 629 SKIP_SPACE(p); |
519 while(*p) { | 630 while(*p) { |
520 /* Transform all relative to absolute, */ | 631 /* Transform all relative to absolute, */ |
521 x = *(args - 2); | 632 x = *(pnts - 2); |
522 y = *(args - 1); | 633 y = *(pnts - 1); |
523 | 634 |
524 switch((cmd = *p++)) { | 635 switch((cmd = *p++)) { |
525 case 'c': | 636 case 'c': |
526 case 'C': | 637 case 'C': |
527 while(*p) { | 638 while(*p) { |
529 SKIP_SPACE(p); | 640 SKIP_SPACE(p); |
530 old = p; | 641 old = p; |
531 SKIP_NUM(p); | 642 SKIP_NUM(p); |
532 if(p == old) | 643 if(p == old) |
533 break; | 644 break; |
534 *args = TO_ABSX; | 645 *pnts = TO_ABSX; |
535 args++; | 646 pnts++; |
536 | 647 |
537 SKIP_SPACE(p); | 648 SKIP_SPACE(p); |
538 old = p; | 649 old = p; |
539 SKIP_NUM(p); | 650 SKIP_NUM(p); |
540 if(p == old) | 651 if(p == old) |
541 return ERR; | 652 return ERR; |
542 *args = TO_ABSY; | 653 *pnts = TO_ABSY; |
543 args++; | 654 pnts++; |
544 | 655 |
545 SKIP_SPACE(p); | 656 SKIP_SPACE(p); |
546 old = p; | 657 old = p; |
547 SKIP_NUM(p); | 658 SKIP_NUM(p); |
548 if(p == old) | 659 if(p == old) |
549 return ERR; | 660 return ERR; |
550 *args = TO_ABSX; | 661 *pnts = TO_ABSX; |
551 args++; | 662 pnts++; |
552 | 663 |
553 SKIP_SPACE(p); | 664 SKIP_SPACE(p); |
554 old = p; | 665 old = p; |
555 SKIP_NUM(p); | 666 SKIP_NUM(p); |
556 if(p == old) | 667 if(p == old) |
557 return ERR; | 668 return ERR; |
558 *args = TO_ABSY; | 669 *pnts = TO_ABSY; |
559 args++; | 670 pnts++; |
560 SKIP_SPACE(p); | 671 SKIP_SPACE(p); |
561 old = p; | 672 old = p; |
562 SKIP_NUM(p); | 673 SKIP_NUM(p); |
563 if(p == old) | 674 if(p == old) |
564 return ERR; | 675 return ERR; |
565 *args = TO_ABSX; | 676 *pnts = TO_ABSX; |
566 args++; | 677 pnts++; |
567 | 678 |
568 SKIP_SPACE(p); | 679 SKIP_SPACE(p); |
569 old = p; | 680 old = p; |
570 SKIP_NUM(p); | 681 SKIP_NUM(p); |
571 if(p == old) | 682 if(p == old) |
572 return ERR; | 683 return ERR; |
573 *args = TO_ABSY; | 684 *pnts = TO_ABSY; |
574 args++; | 685 pnts++; |
575 | 686 |
576 *cmds++ = toupper(cmd); | 687 *cmds++ = toupper(cmd); |
577 } | 688 } |
578 break; | 689 break; |
579 case 's': | 690 case 's': |
585 SKIP_SPACE(p); | 696 SKIP_SPACE(p); |
586 old = p; | 697 old = p; |
587 SKIP_NUM(p); | 698 SKIP_NUM(p); |
588 if(p == old) | 699 if(p == old) |
589 break; | 700 break; |
590 *args = TO_ABSX; | 701 *pnts = TO_ABSX; |
591 args++; | 702 pnts++; |
592 | 703 |
593 SKIP_SPACE(p); | 704 SKIP_SPACE(p); |
594 old = p; | 705 old = p; |
595 SKIP_NUM(p); | 706 SKIP_NUM(p); |
596 if(p == old) | 707 if(p == old) |
597 return ERR; | 708 return ERR; |
598 *args = TO_ABSY; | 709 *pnts = TO_ABSY; |
599 args++; | 710 pnts++; |
600 | 711 |
601 SKIP_SPACE(p); | 712 SKIP_SPACE(p); |
602 old = p; | 713 old = p; |
603 SKIP_NUM(p); | 714 SKIP_NUM(p); |
604 if(p == old) | 715 if(p == old) |
605 return ERR; | 716 return ERR; |
606 *args = TO_ABSX; | 717 *pnts = TO_ABSX; |
607 args++; | 718 pnts++; |
608 | 719 |
609 SKIP_SPACE(p); | 720 SKIP_SPACE(p); |
610 old = p; | 721 old = p; |
611 SKIP_NUM(p); | 722 SKIP_NUM(p); |
612 if(p == old) | 723 if(p == old) |
613 return ERR; | 724 return ERR; |
614 *args = TO_ABSY; | 725 *pnts = TO_ABSY; |
615 args++; | 726 pnts++; |
616 | 727 |
617 *cmds++ = toupper(cmd); | 728 *cmds++ = toupper(cmd); |
618 } | 729 } |
619 break; | 730 break; |
620 case 'm': | 731 case 'm': |
628 SKIP_SPACE(p); | 739 SKIP_SPACE(p); |
629 old = p; | 740 old = p; |
630 SKIP_NUM(p); | 741 SKIP_NUM(p); |
631 if(p == old) | 742 if(p == old) |
632 break; | 743 break; |
633 *args = TO_ABSX; | 744 *pnts = TO_ABSX; |
634 args++; | 745 pnts++; |
635 | 746 |
636 SKIP_SPACE(p); | 747 SKIP_SPACE(p); |
637 old = p; | 748 old = p; |
638 SKIP_NUM(p); | 749 SKIP_NUM(p); |
639 if(p == old) | 750 if(p == old) |
640 return ERR; | 751 return ERR; |
641 *args = TO_ABSY; | 752 *pnts = TO_ABSY; |
642 args++; | 753 pnts++; |
643 | 754 |
644 *cmds++ = toupper(cmd); | 755 *cmds++ = toupper(cmd); |
645 } | 756 } |
646 break; | 757 break; |
647 case 'h': | 758 case 'h': |
652 return ERR; | 763 return ERR; |
653 | 764 |
654 case 'A': | 765 case 'A': |
655 case 'a': | 766 case 'a': |
656 r = sh_path_arc_cmd_arg_fill(cmd, &cmds, | 767 r = sh_path_arc_cmd_arg_fill(cmd, &cmds, |
657 (const char **)&p, &args, | 768 (const char **)&p, &pnts, |
658 &fix_args); | 769 &float_args); |
659 if(r != OK) | 770 if(r != OK) |
660 return ERR; | 771 return ERR; |
661 break; | 772 break; |
662 | 773 |
663 case 'z': | 774 case 'z': |
675 | 786 |
676 /*! \brief Create a path from value of 'data' of SVG path. | 787 /*! \brief Create a path from value of 'data' of SVG path. |
677 */ | 788 */ |
678 shape_t *rdman_shape_path_new(redraw_man_t *rdman, char *data) { | 789 shape_t *rdman_shape_path_new(redraw_man_t *rdman, char *data) { |
679 sh_path_t *path; | 790 sh_path_t *path; |
680 int cmd_cnt, arg_cnt, fix_arg_cnt; | 791 int cmd_cnt, pnt_cnt, float_arg_cnt; |
681 int msz; | 792 int msz; |
682 int r; | 793 int r; |
683 | 794 |
684 r = sh_path_cmd_arg_cnt(data, &cmd_cnt, &arg_cnt, &fix_arg_cnt); | 795 r = sh_path_cmd_arg_cnt(data, &cmd_cnt, &pnt_cnt, |
796 &float_arg_cnt); | |
685 if(r == ERR) | 797 if(r == ERR) |
686 return NULL; | 798 return NULL; |
687 | 799 |
688 /* Align at 4's boundary and keep 2 unused co_aix space | 800 /* Align at 4's boundary and keep 2 unused co_aix space |
689 * to make logic of transformation from relative to absolute | 801 * to make logic of transformation from relative to absolute |
696 path = (sh_path_t *)malloc(sizeof(sh_path_t)); | 808 path = (sh_path_t *)malloc(sizeof(sh_path_t)); |
697 /*! \todo Remove this memset()? */ | 809 /*! \todo Remove this memset()? */ |
698 memset(&path->shape, 0, sizeof(shape_t)); | 810 memset(&path->shape, 0, sizeof(shape_t)); |
699 mb_obj_init(path, MBO_PATH); | 811 mb_obj_init(path, MBO_PATH); |
700 path->cmd_len = cmd_cnt; | 812 path->cmd_len = cmd_cnt; |
701 path->arg_len = arg_cnt; | 813 path->pnt_len = pnt_cnt; |
702 path->fix_arg_len = fix_arg_cnt; | 814 path->float_arg_len = float_arg_cnt; |
703 | 815 |
704 msz = cmd_cnt + sizeof(co_aix) * arg_cnt + sizeof(int) * fix_arg_cnt; | 816 msz = cmd_cnt + sizeof(co_aix) * pnt_cnt + |
817 sizeof(co_aix) * float_arg_cnt; | |
705 path->user_data = (char *)malloc(msz * 2); | 818 path->user_data = (char *)malloc(msz * 2); |
706 if(path->user_data == NULL) { | 819 if(path->user_data == NULL) { |
707 free(path); | 820 free(path); |
708 return NULL; | 821 return NULL; |
709 } | 822 } |
723 rdman_shape_man(rdman, (shape_t *)path); | 836 rdman_shape_man(rdman, (shape_t *)path); |
724 | 837 |
725 return (shape_t *)path; | 838 return (shape_t *)path; |
726 } | 839 } |
727 | 840 |
728 shape_t *rdman_shape_path_new_from_binary(redraw_man_t *rdman, char *commands, co_aix *arg,int arg_cnt,int *fix_arg,int fix_arg_cnt) { | 841 shape_t *rdman_shape_path_new_from_binary(redraw_man_t *rdman, |
842 char *commands, | |
843 co_aix *pnts, int pnt_cnt, | |
844 co_aix *float_args, | |
845 int float_arg_cnt) { | |
729 sh_path_t *path; | 846 sh_path_t *path; |
730 int msz; | 847 int msz; |
731 int cmd_cnt = strlen(commands); | 848 int cmd_cnt = strlen(commands); |
732 | 849 |
733 /*! \todo Use elmpool to manage sh_path_t objects. */ | 850 /*! \todo Use elmpool to manage sh_path_t objects. */ |
734 path = (sh_path_t *)malloc(sizeof(sh_path_t)); | 851 path = (sh_path_t *)malloc(sizeof(sh_path_t)); |
735 /*! \todo Remove this memset()? */ | 852 /*! \todo Remove this memset()? */ |
736 memset(&path->shape, 0, sizeof(shape_t)); | 853 memset(&path->shape, 0, sizeof(shape_t)); |
737 mb_obj_init(path, MBO_PATH); | 854 mb_obj_init(path, MBO_PATH); |
738 path->cmd_len = strlen(commands); | 855 cmd_cnt = (cmd_cnt + 3) & ~0x3; |
739 path->arg_len = arg_cnt; | 856 path->cmd_len = cmd_cnt; |
740 path->fix_arg_len = fix_arg_cnt; | 857 path->pnt_len = pnt_cnt; |
741 msz = cmd_cnt + sizeof(co_aix) * arg_cnt + sizeof(int) * fix_arg_cnt; | 858 path->float_arg_len = float_arg_cnt; |
859 msz = cmd_cnt + sizeof(co_aix) * pnt_cnt + | |
860 sizeof(co_aix) * float_arg_cnt; | |
742 path->user_data = (char *)malloc(msz * 2); | 861 path->user_data = (char *)malloc(msz * 2); |
743 if(path->user_data == NULL) { | 862 if(path->user_data == NULL) { |
744 free(path); | 863 free(path); |
745 return NULL; | 864 return NULL; |
746 } | 865 } |
747 | 866 |
748 path->dev_data = path->user_data + msz; | 867 path->dev_data = path->user_data + msz; |
749 memcpy(path->user_data,commands,cmd_cnt); | 868 memcpy(path->user_data, commands, strlen(commands)); |
750 memcpy(path->user_data+cmd_cnt,arg, sizeof(co_aix)*arg_cnt); | 869 memcpy(path->user_data + cmd_cnt, pnts, sizeof(co_aix) * pnt_cnt); |
751 memcpy(path->user_data+cmd_cnt+arg_cnt*sizeof(co_aix),fix_arg, sizeof(int)*fix_arg_cnt); | 870 memcpy(path->user_data + cmd_cnt + pnt_cnt * sizeof(co_aix), |
871 float_args, sizeof(co_aix) * float_arg_cnt); | |
752 memcpy(path->dev_data, path->user_data, msz); | 872 memcpy(path->dev_data, path->user_data, msz); |
753 | 873 |
754 path->shape.free = sh_path_free; | 874 path->shape.free = sh_path_free; |
755 | 875 |
756 rdman_shape_man(rdman, (shape_t *)path); | 876 rdman_shape_man(rdman, (shape_t *)path); |
757 | 877 |
758 return (shape_t *)path; | 878 return (shape_t *)path; |
759 } | 879 } |
760 | 880 |
762 /*! \brief Transform a path from user space to device space. | 882 /*! \brief Transform a path from user space to device space. |
763 * | 883 * |
764 */ | 884 */ |
765 void sh_path_transform(shape_t *shape) { | 885 void sh_path_transform(shape_t *shape) { |
766 sh_path_t *path; | 886 sh_path_t *path; |
767 co_aix *user_args, *dev_args; | 887 co_aix *pnts, *dev_pnts; |
768 co_aix (*poses)[2]; | 888 co_aix (*poses)[2]; |
769 area_t *area; | 889 area_t *area; |
770 int arg_len; | 890 int pnt_len; |
771 int i; | 891 int i; |
772 | 892 |
773 ASSERT(shape->type == SHT_PATH); | 893 ASSERT(shape->type == SHT_PATH); |
774 ASSERT((shape->arg_len & 0x1) == 0); | 894 ASSERT((shape->pnt_len & 0x1) == 0); |
775 | 895 |
776 path = (sh_path_t *)shape; | 896 path = (sh_path_t *)shape; |
777 user_args = (co_aix *)(path->user_data + path->cmd_len); | 897 pnts = (co_aix *)(path->user_data + path->cmd_len); |
778 dev_args = (co_aix *)(path->dev_data + path->cmd_len); | 898 dev_pnts = (co_aix *)(path->dev_data + path->cmd_len); |
779 arg_len = path->arg_len; | 899 pnt_len = path->pnt_len; |
780 for(i = 0; i < arg_len; i += 2) { | 900 for(i = 0; i < pnt_len; i += 2) { |
781 dev_args[0] = *user_args++; | 901 dev_pnts[0] = *pnts++; |
782 dev_args[1] = *user_args++; | 902 dev_pnts[1] = *pnts++; |
783 coord_trans_pos(shape->coord, dev_args, dev_args + 1); | 903 coord_trans_pos(shape->coord, dev_pnts, dev_pnts + 1); |
784 dev_args += 2; | 904 dev_pnts += 2; |
785 } | 905 } |
786 | 906 |
787 if(path->shape.geo) { | 907 if(path->shape.geo) { |
788 poses = (co_aix (*)[2])(path->dev_data + path->cmd_len); | 908 poses = (co_aix (*)[2])(path->dev_data + path->cmd_len); |
789 geo_from_positions(path->shape.geo, arg_len / 2, poses); | 909 geo_from_positions(path->shape.geo, pnt_len / 2, poses); |
790 area = shape->geo->cur_area; | 910 area = shape->geo->cur_area; |
791 area->x -= shape->stroke_width / 2 + 0.5; | 911 area->x -= shape->stroke_width / 2 + 0.5; |
792 area->y -= shape->stroke_width / 2 + 0.5; | 912 area->y -= shape->stroke_width / 2 + 0.5; |
793 area->w += shape->stroke_width + 1; | 913 area->w += shape->stroke_width + 1; |
794 area->h += shape->stroke_width + 1; | 914 area->h += shape->stroke_width + 1; |
797 | 917 |
798 static void sh_path_path(shape_t *shape, mbe_t *cr) { | 918 static void sh_path_path(shape_t *shape, mbe_t *cr) { |
799 sh_path_t *path; | 919 sh_path_t *path; |
800 int cmd_len; | 920 int cmd_len; |
801 char *cmds, cmd; | 921 char *cmds, cmd; |
802 const co_aix *args; | 922 const co_aix *pnts; |
803 const int *fix_args; | 923 const co_aix *float_args; |
804 co_aix x, y, x1, y1, x2, y2; | 924 co_aix x, y, x1, y1, x2, y2; |
805 int i; | 925 int i; |
806 | 926 |
807 ASSERT(shape->type == SHT_PATH); | 927 ASSERT(shape->type == SHT_PATH); |
808 | 928 |
809 path = (sh_path_t *)shape; | 929 path = (sh_path_t *)shape; |
810 cmd_len = path->cmd_len; | 930 cmd_len = path->cmd_len; |
811 cmds = path->dev_data; | 931 cmds = path->dev_data; |
812 args = (co_aix *)(cmds + cmd_len); | 932 pnts = (co_aix *)(cmds + cmd_len); |
813 fix_args = (int *)(cmds + cmd_len + path->arg_len * sizeof(co_aix)); | 933 float_args = (co_aix *)(cmds + cmd_len + path->pnt_len * sizeof(co_aix)); |
814 x = y = x1 = y1 = x2 = y2 = 0; | 934 x = y = x1 = y1 = x2 = y2 = 0; |
815 for(i = 0; i < cmd_len; i++) { | 935 for(i = 0; i < cmd_len; i++) { |
816 /* All path commands and arguments are transformed | 936 /* All path commands and arguments are transformed |
817 * to absoluted form. | 937 * to absoluted form. |
818 */ | 938 */ |
819 cmd = *cmds++; | 939 cmd = *cmds++; |
820 switch(cmd) { | 940 switch(cmd) { |
821 case 'M': | 941 case 'M': |
822 x = *args++; | 942 x = *pnts++; |
823 y = *args++; | 943 y = *pnts++; |
824 mbe_move_to(cr, x, y); | 944 mbe_move_to(cr, x, y); |
825 break; | 945 break; |
826 case 'L': | 946 case 'L': |
827 x = *args++; | 947 x = *pnts++; |
828 y = *args++; | 948 y = *pnts++; |
829 mbe_line_to(cr, x, y); | 949 mbe_line_to(cr, x, y); |
830 break; | 950 break; |
831 case 'C': | 951 case 'C': |
832 x1 = *args++; | 952 x1 = *pnts++; |
833 y1 = *args++; | 953 y1 = *pnts++; |
834 x2 = *args++; | 954 x2 = *pnts++; |
835 y2 = *args++; | 955 y2 = *pnts++; |
836 x = *args++; | 956 x = *pnts++; |
837 y = *args++; | 957 y = *pnts++; |
838 mbe_curve_to(cr, x1, y1, x2, y2, x, y); | 958 mbe_curve_to(cr, x1, y1, x2, y2, x, y); |
839 break; | 959 break; |
840 case 'S': | 960 case 'S': |
841 x1 = x + x - x2; | 961 x1 = x + x - x2; |
842 y1 = y + y - y2; | 962 y1 = y + y - y2; |
843 x2 = *args++; | 963 x2 = *pnts++; |
844 y2 = *args++; | 964 y2 = *pnts++; |
845 x = *args++; | 965 x = *pnts++; |
846 y = *args++; | 966 y = *pnts++; |
847 mbe_curve_to(cr, x1, y1, x2, y2, x, y); | 967 mbe_curve_to(cr, x1, y1, x2, y2, x, y); |
848 break; | 968 break; |
849 case 'Q': | 969 case 'Q': |
850 x1 = *args++; | 970 x1 = *pnts++; |
851 y1 = *args++; | 971 y1 = *pnts++; |
852 x2 = x1; | 972 x2 = x1; |
853 y2 = y1; | 973 y2 = y1; |
854 x = *args++; | 974 x = *pnts++; |
855 y = *args++; | 975 y = *pnts++; |
856 mbe_curve_to(cr, x1, y1, x2, y2, x, y); | 976 mbe_curve_to(cr, x1, y1, x2, y2, x, y); |
857 break; | 977 break; |
858 case 'T': | 978 case 'T': |
859 x1 = x + x - x2; | 979 x1 = x + x - x2; |
860 y1 = y + y - y2; | 980 y1 = y + y - y2; |
861 x2 = x1; | 981 x2 = x1; |
862 y2 = y1; | 982 y2 = y1; |
863 x = *args++; | 983 x = *pnts++; |
864 y = *args++; | 984 y = *pnts++; |
865 mbe_curve_to(cr, x1, y1, x2, y2, x, y); | 985 mbe_curve_to(cr, x1, y1, x2, y2, x, y); |
866 break; | 986 break; |
867 case 'A': | 987 case 'A': |
868 sh_path_arc_path(cr, &args, &fix_args); | 988 _sh_path_arc_path(cr, path, &pnts, &float_args); |
869 break; | 989 break; |
870 case 'Z': | 990 case 'Z': |
871 mbe_close_path(cr); | 991 mbe_close_path(cr); |
872 break; | 992 break; |
873 case '\x0': | 993 case '\x0': |
885 | 1005 |
886 #include <CUnit/Basic.h> | 1006 #include <CUnit/Basic.h> |
887 | 1007 |
888 void test_rdman_shape_path_new(void) { | 1008 void test_rdman_shape_path_new(void) { |
889 sh_path_t *path; | 1009 sh_path_t *path; |
890 co_aix *args; | 1010 co_aix *pnts; |
891 | 1011 |
892 path = (sh_path_t *)rdman_shape_path_new(NULL, "M 33 25l33 55c 33 87 44 22 55 99L33 77z"); | 1012 path = (sh_path_t *)rdman_shape_path_new(NULL, "M 33 25l33 55c 33 87 44 22 55 99L33 77z"); |
893 CU_ASSERT(path != NULL); | 1013 CU_ASSERT(path != NULL); |
894 CU_ASSERT(path->cmd_len == ((5 + RESERVED_AIXS + 3) & ~0x3)); | 1014 CU_ASSERT(path->cmd_len == ((5 + RESERVED_AIXS + 3) & ~0x3)); |
895 CU_ASSERT(path->arg_len == 12); | 1015 CU_ASSERT(path->pnt_len == 12); |
896 CU_ASSERT(strncmp(path->user_data, "MLCLZ", 5) == 0); | 1016 CU_ASSERT(strncmp(path->user_data, "MLCLZ", 5) == 0); |
897 CU_ASSERT(strncmp(path->dev_data, "MLCLZ", 5) == 0); | 1017 CU_ASSERT(strncmp(path->dev_data, "MLCLZ", 5) == 0); |
898 | 1018 |
899 args = (co_aix *)(path->user_data + path->cmd_len); | 1019 pnts = (co_aix *)(path->user_data + path->cmd_len); |
900 CU_ASSERT(args[0] == 33); | 1020 CU_ASSERT(pnts[0] == 33); |
901 CU_ASSERT(args[1] == 25); | 1021 CU_ASSERT(pnts[1] == 25); |
902 CU_ASSERT(args[2] == 66); | 1022 CU_ASSERT(pnts[2] == 66); |
903 CU_ASSERT(args[3] == 80); | 1023 CU_ASSERT(pnts[3] == 80); |
904 CU_ASSERT(args[4] == 99); | 1024 CU_ASSERT(pnts[4] == 99); |
905 CU_ASSERT(args[5] == 167); | 1025 CU_ASSERT(pnts[5] == 167); |
906 CU_ASSERT(args[6] == 110); | 1026 CU_ASSERT(pnts[6] == 110); |
907 CU_ASSERT(args[7] == 102); | 1027 CU_ASSERT(pnts[7] == 102); |
908 CU_ASSERT(args[8] == 121); | 1028 CU_ASSERT(pnts[8] == 121); |
909 CU_ASSERT(args[9] == 179); | 1029 CU_ASSERT(pnts[9] == 179); |
910 CU_ASSERT(args[10] == 33); | 1030 CU_ASSERT(pnts[10] == 33); |
911 CU_ASSERT(args[11] == 77); | 1031 CU_ASSERT(pnts[11] == 77); |
912 sh_path_free((shape_t *)path); | 1032 sh_path_free((shape_t *)path); |
913 } | 1033 } |
914 | 1034 |
915 void test_path_transform(void) { | 1035 void test_path_transform(void) { |
916 sh_path_t *path; | 1036 sh_path_t *path; |
917 co_aix *args; | 1037 co_aix *pnts; |
918 coord_t coord; | 1038 coord_t coord; |
919 geo_t geo; | 1039 geo_t geo; |
920 | 1040 |
921 path = (sh_path_t *)rdman_shape_path_new(NULL, "M 33 25l33 55C 33 87 44 22 55 99L33 77z"); | 1041 path = (sh_path_t *)rdman_shape_path_new(NULL, "M 33 25l33 55C 33 87 44 22 55 99L33 77z"); |
922 CU_ASSERT(path != NULL); | 1042 CU_ASSERT(path != NULL); |
923 CU_ASSERT(path->cmd_len == ((5 + RESERVED_AIXS + 3) & ~0x3)); | 1043 CU_ASSERT(path->cmd_len == ((5 + RESERVED_AIXS + 3) & ~0x3)); |
924 CU_ASSERT(path->arg_len == 12); | 1044 CU_ASSERT(path->pnt_len == 12); |
925 CU_ASSERT(strncmp(path->user_data, "MLCLZ", 5) == 0); | 1045 CU_ASSERT(strncmp(path->user_data, "MLCLZ", 5) == 0); |
926 CU_ASSERT(strncmp(path->dev_data, "MLCLZ", 5) == 0); | 1046 CU_ASSERT(strncmp(path->dev_data, "MLCLZ", 5) == 0); |
927 | 1047 |
928 geo_init(&geo); | 1048 geo_init(&geo); |
929 path->shape.geo = &geo; | 1049 path->shape.geo = &geo; |
936 coord.aggr_matrix[4] = 2; | 1056 coord.aggr_matrix[4] = 2; |
937 coord.aggr_matrix[5] = 0; | 1057 coord.aggr_matrix[5] = 0; |
938 path->shape.coord = &coord; | 1058 path->shape.coord = &coord; |
939 sh_path_transform((shape_t *)path); | 1059 sh_path_transform((shape_t *)path); |
940 | 1060 |
941 args = (co_aix *)(path->dev_data + path->cmd_len); | 1061 pnts = (co_aix *)(path->dev_data + path->cmd_len); |
942 CU_ASSERT(args[0] == 34); | 1062 CU_ASSERT(pnts[0] == 34); |
943 CU_ASSERT(args[1] == 50); | 1063 CU_ASSERT(pnts[1] == 50); |
944 CU_ASSERT(args[2] == 67); | 1064 CU_ASSERT(pnts[2] == 67); |
945 CU_ASSERT(args[3] == 160); | 1065 CU_ASSERT(pnts[3] == 160); |
946 CU_ASSERT(args[4] == 34); | 1066 CU_ASSERT(pnts[4] == 34); |
947 CU_ASSERT(args[5] == 174); | 1067 CU_ASSERT(pnts[5] == 174); |
948 CU_ASSERT(args[6] == 45); | 1068 CU_ASSERT(pnts[6] == 45); |
949 CU_ASSERT(args[7] == 44); | 1069 CU_ASSERT(pnts[7] == 44); |
950 CU_ASSERT(args[8] == 56); | 1070 CU_ASSERT(pnts[8] == 56); |
951 CU_ASSERT(args[9] == 198); | 1071 CU_ASSERT(pnts[9] == 198); |
952 CU_ASSERT(args[10] == 34); | 1072 CU_ASSERT(pnts[10] == 34); |
953 CU_ASSERT(args[11] == 154); | 1073 CU_ASSERT(pnts[11] == 154); |
954 | 1074 |
955 sh_path_free((shape_t *)path); | 1075 sh_path_free((shape_t *)path); |
956 } | 1076 } |
957 | 1077 |
958 void test_spaces_head_tail(void) { | 1078 void test_spaces_head_tail(void) { |