Mercurial > MadButterfly
comparison src/shape_stext.c @ 422:c6c0d017dc8e
Use DARRAY to manage variable length list
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Tue, 28 Jul 2009 15:11:42 +0800 |
parents | 1e48453bb282 |
children | 3ba48126c49c |
comparison
equal
deleted
inserted
replaced
421:1e48453bb282 | 422:c6c0d017dc8e |
---|---|
1 #include <stdio.h> | 1 #include <stdio.h> |
2 #include <cairo.h> | 2 #include <cairo.h> |
3 #include <cairo-ft.h> | 3 #include <cairo-ft.h> |
4 #include <fontconfig/fontconfig.h> | 4 #include <fontconfig/fontconfig.h> |
5 #include "mb_shapes.h" | 5 #include "mb_shapes.h" |
6 #include "mb_tools.h" | |
6 | 7 |
7 #ifdef UNITTEST | 8 #ifdef UNITTEST |
8 typedef struct _ut_shape { | 9 typedef struct _ut_shape { |
9 co_aix aggr[6]; | 10 co_aix aggr[6]; |
10 void (*free)(struct _ut_shape *); | 11 void (*free)(struct _ut_shape *); |
279 void mb_font_face_free(mb_font_face_t *face) { | 280 void mb_font_face_free(mb_font_face_t *face) { |
280 ASSERT(face != NULL); | 281 ASSERT(face != NULL); |
281 free_font_face(face); | 282 free_font_face(face); |
282 } | 283 } |
283 | 284 |
285 DARRAY(scaled_fonts_lst, mb_scaled_font_t *); | |
286 DARRAY_DEFINE(scaled_fonts_lst, mb_scaled_font_t *); | |
287 DARRAY(style_blks_lst, mb_style_blk_t); | |
288 DARRAY_DEFINE_ADV(style_blks_lst, mb_style_blk_t); | |
289 | |
284 /*! \brief A simple implementation of text shape. | 290 /*! \brief A simple implementation of text shape. |
285 * | 291 * |
286 */ | 292 */ |
287 typedef struct _sh_stext { | 293 typedef struct _sh_stext { |
288 shape_t shape; | 294 shape_t shape; |
289 const char *txt; /*!< \brief Text to be showed */ | 295 const char *txt; /*!< \brief Text to be showed */ |
290 const mb_style_blk_t *style_blks; /*!< \brief Style of text */ | 296 style_blks_lst_t style_blks; |
291 int nblks; /*!< \brief Number of valid style | |
292 * blocks */ | |
293 int max_nblks; /*!< \brief Available space of | |
294 * style_blks */ | |
295 co_aix x, y; | 297 co_aix x, y; |
296 mb_scaled_font_t **scaled_fonts; | 298 scaled_fonts_lst_t scaled_fonts; |
297 int nscaled; | |
298 int maxscaled; | |
299 mb_text_extents_t extents; | 299 mb_text_extents_t extents; |
300 } sh_stext_t; | 300 } sh_stext_t; |
301 | 301 |
302 static | 302 static |
303 void _rdman_shape_stext_free(shape_t *shape) { | 303 void _rdman_shape_stext_free(shape_t *shape) { |
304 sh_stext_t *txt_o = (sh_stext_t *)shape; | 304 sh_stext_t *txt_o = (sh_stext_t *)shape; |
305 int i; | 305 int i; |
306 | 306 |
307 if(txt_o->style_blks) | 307 DARRAY_DESTROY(&txt_o->style_blks); |
308 free((void *)txt_o->style_blks); | 308 |
309 if(txt_o->scaled_fonts) { | 309 for(i = 0; i < txt_o->scaled_fonts.num; i++) |
310 for(i = 0; i < txt_o->nscaled; i++) | 310 scaled_font_free(txt_o->scaled_fonts.ds[i]); |
311 scaled_font_free(txt_o->scaled_fonts[i]); | 311 DARRAY_DESTROY(&txt_o->scaled_fonts); |
312 free(txt_o->scaled_fonts); | 312 |
313 } | |
314 if(txt_o->txt) | 313 if(txt_o->txt) |
315 free((void *)txt_o->txt); | 314 free((void *)txt_o->txt); |
316 | 315 |
317 free(txt_o); | 316 free(txt_o); |
318 } | 317 } |
329 | 328 |
330 memset(&txt_o->shape, 0, sizeof(shape_t)); | 329 memset(&txt_o->shape, 0, sizeof(shape_t)); |
331 mb_obj_init(txt_o, MBO_STEXT); | 330 mb_obj_init(txt_o, MBO_STEXT); |
332 | 331 |
333 txt_o->txt = strdup(txt); | 332 txt_o->txt = strdup(txt); |
334 txt_o->style_blks = NULL; | 333 DARRAY_INIT(&txt_o->style_blks); |
335 txt_o->nblks = 0; | |
336 txt_o->max_nblks = 0; | |
337 txt_o->x = x; | 334 txt_o->x = x; |
338 txt_o->y = y; | 335 txt_o->y = y; |
339 txt_o->scaled_fonts = NULL; | 336 DARRAY_INIT(&txt_o->scaled_fonts); |
340 txt_o->nscaled = 0; | |
341 txt_o->maxscaled = 0; | |
342 | 337 |
343 if(txt_o->txt == NULL) { | 338 if(txt_o->txt == NULL) { |
344 free(txt_o); | 339 free(txt_o); |
345 txt_o = NULL; | 340 txt_o = NULL; |
346 } | 341 } |
459 * to create correct extents for full text string with style blocks. | 454 * to create correct extents for full text string with style blocks. |
460 */ | 455 */ |
461 static | 456 static |
462 void compute_styled_extents_n_scaled_font(sh_stext_t *txt_o) { | 457 void compute_styled_extents_n_scaled_font(sh_stext_t *txt_o) { |
463 mb_text_extents_t sub_extents; | 458 mb_text_extents_t sub_extents; |
464 const mb_style_blk_t *blk; | 459 mb_style_blk_t *blk; |
460 style_blks_lst_t *style_blks; | |
465 int blk_txt_len; | 461 int blk_txt_len; |
466 mb_scaled_font_t **scaled_font; | 462 mb_scaled_font_t *scaled; |
463 scaled_fonts_lst_t *scaled_fonts; | |
467 char *txt, saved; | 464 char *txt, saved; |
468 int i, nscaled; | 465 int i, nscaled; |
469 | 466 |
470 memset(&txt_o->extents, sizeof(mb_text_extents_t), 0); | 467 memset(&txt_o->extents, sizeof(mb_text_extents_t), 0); |
471 | 468 |
472 blk = txt_o->style_blks; | 469 scaled_fonts = &txt_o->scaled_fonts; |
473 | 470 for(i = 0; i < scaled_fonts->num; i++) |
474 scaled_font = txt_o->scaled_fonts; | 471 scaled_font_free(scaled_fonts->ds[i]); |
475 nscaled = txt_o->nscaled; | 472 DARRAY_CLEAN(scaled_fonts); |
476 for(i = 0; i < nscaled; i++) { | 473 |
477 scaled_font_free(*scaled_font); | 474 style_blks = &txt_o->style_blks; |
478 scaled_font++; | 475 blk = style_blks->ds; |
479 } | 476 |
480 txt_o->nscaled = 0; | |
481 | |
482 if(txt_o->maxscaled >= txt_o->nblks) | |
483 scaled_font = txt_o->scaled_fonts; | |
484 else { | |
485 scaled_font = (mb_scaled_font_t **) | |
486 realloc(txt_o->scaled_fonts, | |
487 txt_o->nblks * sizeof(mb_scaled_font_t *)); | |
488 ASSERT(scaled_font != NULL); | |
489 | |
490 txt_o->maxscaled = txt_o->nblks; | |
491 txt_o->scaled_fonts = scaled_font; | |
492 } | |
493 | |
494 txt = (char *)txt_o->txt; | 477 txt = (char *)txt_o->txt; |
495 for(i = 0; i < txt_o->nblks; i++) { | 478 for(i = 0; i < style_blks->num; i++) { |
496 *scaled_font = make_scaled_font_face(txt_o, blk->face, | 479 scaled = make_scaled_font_face(txt_o, blk->face, |
497 0, 0, blk->font_sz); | 480 0, 0, blk->font_sz); |
498 ASSERT(*scaled_font != NULL); | 481 ASSERT(scaled != NULL); |
482 scaled_fonts_lst_add(scaled_fonts, scaled); | |
499 | 483 |
500 blk_txt_len = compute_utf8_chars_sz(txt, blk->n_chars); | 484 blk_txt_len = compute_utf8_chars_sz(txt, blk->n_chars); |
501 ASSERT(blk_txt_len != ERR); | 485 ASSERT(blk_txt_len != ERR); |
502 | 486 |
503 saved = txt[blk_txt_len]; | 487 saved = txt[blk_txt_len]; |
504 txt[blk_txt_len] = 0; | 488 txt[blk_txt_len] = 0; |
505 compute_text_extents(*scaled_font, txt, &sub_extents); | 489 compute_text_extents(scaled, txt, &sub_extents); |
506 txt[blk_txt_len] = saved; | 490 txt[blk_txt_len] = saved; |
507 | 491 |
508 extent_extents(&txt_o->extents, &sub_extents); | 492 extent_extents(&txt_o->extents, &sub_extents); |
509 | 493 |
510 scaled_font++; | |
511 blk++; | 494 blk++; |
512 txt += blk_txt_len; | 495 txt += blk_txt_len; |
513 } | 496 } |
514 | |
515 txt_o->nscaled = txt_o->nblks; | |
516 } | 497 } |
517 | 498 |
518 /* | 499 /* |
519 * What we have to do in sh_stext_transform() is | 500 * What we have to do in sh_stext_transform() is |
520 * - computing bounding box for the text, | 501 * - computing bounding box for the text, |
556 | 537 |
557 int sh_stext_set_style(shape_t *shape, | 538 int sh_stext_set_style(shape_t *shape, |
558 const mb_style_blk_t *blks, | 539 const mb_style_blk_t *blks, |
559 int nblks) { | 540 int nblks) { |
560 sh_stext_t *txt_o = (sh_stext_t *)shape; | 541 sh_stext_t *txt_o = (sh_stext_t *)shape; |
542 style_blks_lst_t *style_blks; | |
561 mb_style_blk_t *new_blks; | 543 mb_style_blk_t *new_blks; |
562 int sz; | 544 int sz; |
563 | 545 |
564 ASSERT(txt_o != NULL); | 546 ASSERT(txt_o != NULL); |
565 ASSERT(nblks >= 0); | 547 ASSERT(nblks >= 0); |
566 | 548 |
567 if(nblks > txt_o->max_nblks) { | 549 style_blks = &txt_o->style_blks; |
568 sz = nblks * sizeof(mb_style_blk_t); | 550 DARRAY_CLEAN(style_blks); |
569 new_blks = (mb_style_blk_t *)realloc((void *)txt_o->style_blks, sz); | 551 style_blks_lst_adv(style_blks, nblks); |
570 if(new_blks == NULL) | 552 |
571 return ERR; | 553 memcpy(style_blks->ds, |
572 | |
573 txt_o->style_blks = new_blks; | |
574 txt_o->max_nblks = nblks; | |
575 } | |
576 | |
577 memcpy((mb_style_blk_t *)txt_o->style_blks, | |
578 blks, nblks * sizeof(mb_style_blk_t)); | 554 blks, nblks * sizeof(mb_style_blk_t)); |
579 txt_o->nblks = nblks; | 555 |
580 | |
581 return OK; | 556 return OK; |
582 } | 557 } |
583 | 558 |
584 #ifdef UNITTEST | 559 #ifdef UNITTEST |
585 | 560 |