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