comparison src/shape_path.c @ 12:79e9edf4c00a

Add redraw manager
author Thinker K.F. Li <thinker@branda.to>
date Mon, 28 Jul 2008 17:45:36 +0800
parents 128af06c876c
children c2ce186a5c37
comparison
equal deleted inserted replaced
11:128af06c876c 12:79e9edf4c00a
8 /*! \brief Implement respective objects for SVG path tag. 8 /*! \brief Implement respective objects for SVG path tag.
9 * 9 *
10 * In user_data or dev_data, 0x00 bytes are padding after commands. 10 * In user_data or dev_data, 0x00 bytes are padding after commands.
11 * No commands other than 0x00 can resident after 0x00 itself. 11 * No commands other than 0x00 can resident after 0x00 itself.
12 * It means command processing code can skip commands after a 0x00. 12 * It means command processing code can skip commands after a 0x00.
13 *
14 * Shapes should check if shape_t::geo is assigned. Once transformation
15 * matrics are changed, shape objects should update shape_t::geo if
16 * it is assigned.
13 */ 17 */
14 typedef struct _sh_path { 18 typedef struct _sh_path {
15 shape_t shape; 19 shape_t shape;
16 int cmd_len; 20 int cmd_len;
17 int arg_len; 21 int arg_len;
350 */ 354 */
351 cmd_cnt += RESERVED_AIXS; 355 cmd_cnt += RESERVED_AIXS;
352 cmd_cnt = (cmd_cnt + 3) & ~0x3; 356 cmd_cnt = (cmd_cnt + 3) & ~0x3;
353 357
354 path = (sh_path_t *)malloc(sizeof(sh_path_t)); 358 path = (sh_path_t *)malloc(sizeof(sh_path_t));
359 memset(&path->shape, 0, sizeof(shape_t));
355 path->shape.sh_type = SHT_PATH; 360 path->shape.sh_type = SHT_PATH;
356 path->cmd_len = cmd_cnt; 361 path->cmd_len = cmd_cnt;
357 path->arg_len = arg_cnt; 362 path->arg_len = arg_cnt;
358 path->user_data = (char *)malloc(cmd_cnt + sizeof(co_aix) * arg_cnt); 363 path->user_data = (char *)malloc(cmd_cnt + sizeof(co_aix) * arg_cnt);
359 if(path->user_data == NULL) { 364 if(path->user_data == NULL) {
383 /*! \brief Transform a path from user space to device space. 388 /*! \brief Transform a path from user space to device space.
384 * 389 *
385 * TODO: associate coord_t with shape objects and transform them 390 * TODO: associate coord_t with shape objects and transform them
386 * automatically. 391 * automatically.
387 */ 392 */
388 void sh_path_transform(shape_t *shape, coord_t *coord) { 393 void sh_path_transform(shape_t *shape) {
389 sh_path_t *path; 394 sh_path_t *path;
390 co_aix *user_args, *dev_args; 395 co_aix *user_args, *dev_args;
396 co_aix (*poses)[2];
397 int arg_len;
391 int i; 398 int i;
392 399
393 ASSERT(shape->type == SHT_PATH); 400 ASSERT(shape->type == SHT_PATH);
394 ASSERT((shape->arg_len & 0x1) == 0); 401 ASSERT((shape->arg_len & 0x1) == 0);
395 402
396 path = (sh_path_t *)shape; 403 path = (sh_path_t *)shape;
397 user_args = (co_aix *)(path->user_data + path->cmd_len); 404 user_args = (co_aix *)(path->user_data + path->cmd_len);
398 dev_args = (co_aix *)(path->dev_data + path->cmd_len); 405 dev_args = (co_aix *)(path->dev_data + path->cmd_len);
399 for(i = 0; i < path->arg_len; i += 2) { 406 arg_len = path->arg_len;
407 for(i = 0; i < arg_len; i += 2) {
400 dev_args[0] = *user_args++; 408 dev_args[0] = *user_args++;
401 dev_args[1] = *user_args++; 409 dev_args[1] = *user_args++;
402 coord_trans_pos(coord, dev_args, dev_args + 1); 410 coord_trans_pos(shape->coord, dev_args, dev_args + 1);
403 dev_args += 2; 411 dev_args += 2;
412 }
413
414 if(path->shape.geo) {
415 poses = (co_aix (*)[2])(path->dev_data + path->cmd_len);
416 geo_init(path->shape.geo, arg_len / 2, poses);
404 } 417 }
405 } 418 }
406 419
407 void sh_path_draw(shape_t *shape, cairo_t *cr) { 420 void sh_path_draw(shape_t *shape, cairo_t *cr) {
408 sh_path_t *path; 421 sh_path_t *path;
560 573
561 void test_path_transform(void) { 574 void test_path_transform(void) {
562 sh_path_t *path; 575 sh_path_t *path;
563 co_aix *args; 576 co_aix *args;
564 coord_t coord; 577 coord_t coord;
578 geo_t geo;
565 579
566 path = (sh_path_t *)sh_path_new("M 33 25l33 55C 33 87 44 22 55 99L33 77z"); 580 path = (sh_path_t *)sh_path_new("M 33 25l33 55C 33 87 44 22 55 99L33 77z");
567 CU_ASSERT(path != NULL); 581 CU_ASSERT(path != NULL);
568 CU_ASSERT(path->cmd_len == ((5 + RESERVED_AIXS + 3) & ~0x3)); 582 CU_ASSERT(path->cmd_len == ((5 + RESERVED_AIXS + 3) & ~0x3));
569 CU_ASSERT(path->arg_len == 12); 583 CU_ASSERT(path->arg_len == 12);
570 CU_ASSERT(strcmp(path->user_data, "MLCLZ") == 0); 584 CU_ASSERT(strcmp(path->user_data, "MLCLZ") == 0);
571 CU_ASSERT(strcmp(path->dev_data, "MLCLZ") == 0); 585 CU_ASSERT(strcmp(path->dev_data, "MLCLZ") == 0);
572 586
587 path->shape.geo = &geo;
588 geo.shape = (shape_t *)path;
589
573 coord.aggr_matrix[0] = 1; 590 coord.aggr_matrix[0] = 1;
574 coord.aggr_matrix[1] = 0; 591 coord.aggr_matrix[1] = 0;
575 coord.aggr_matrix[2] = 1; 592 coord.aggr_matrix[2] = 1;
576 coord.aggr_matrix[3] = 0; 593 coord.aggr_matrix[3] = 0;
577 coord.aggr_matrix[4] = 2; 594 coord.aggr_matrix[4] = 2;
578 coord.aggr_matrix[5] = 0; 595 coord.aggr_matrix[5] = 0;
579 sh_path_transform((shape_t *)path, &coord); 596 path->shape.coord = &coord;
597 sh_path_transform((shape_t *)path);
580 598
581 args = (co_aix *)(path->dev_data + path->cmd_len); 599 args = (co_aix *)(path->dev_data + path->cmd_len);
582 CU_ASSERT(args[0] == 34); 600 CU_ASSERT(args[0] == 34);
583 CU_ASSERT(args[1] == 50); 601 CU_ASSERT(args[1] == 50);
584 CU_ASSERT(args[2] == 67); 602 CU_ASSERT(args[2] == 67);
589 CU_ASSERT(args[7] == 44); 607 CU_ASSERT(args[7] == 44);
590 CU_ASSERT(args[8] == 56); 608 CU_ASSERT(args[8] == 56);
591 CU_ASSERT(args[9] == 198); 609 CU_ASSERT(args[9] == 198);
592 CU_ASSERT(args[10] == 34); 610 CU_ASSERT(args[10] == 34);
593 CU_ASSERT(args[11] == 154); 611 CU_ASSERT(args[11] == 154);
612
594 sh_path_free((shape_t *)path); 613 sh_path_free((shape_t *)path);
595 } 614 }
596 615
597 void test_spaces_head_tail(void) { 616 void test_spaces_head_tail(void) {
598 sh_path_t *path; 617 sh_path_t *path;