Mercurial > MadButterfly
comparison src/shape_stext.c @ 410:1a923ea699c1
shape_stext.c, now, is unittested.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 08 Jul 2009 21:12:14 +0800 |
parents | 92a459a1c5aa |
children | 1633551e495d |
comparison
equal
deleted
inserted
replaced
409:1e9b615a47e8 | 410:1a923ea699c1 |
---|---|
1 #ifdef SHAPE_STEXT | |
2 | |
3 #include <stdio.h> | 1 #include <stdio.h> |
4 #include <cairo.h> | 2 #include <cairo.h> |
5 #include <cairo-ft.h> | 3 #include <cairo-ft.h> |
6 #include <fontconfig/fontconfig.h> | 4 #include <fontconfig/fontconfig.h> |
7 #include "mb_shapes.h" | 5 #include "mb_shapes.h" |
87 if(ptn == NULL || p == NULL) | 85 if(ptn == NULL || p == NULL) |
88 goto err; | 86 goto err; |
89 | 87 |
90 val.type = FcTypeString; | 88 val.type = FcTypeString; |
91 val.u.s = family; | 89 val.u.s = family; |
92 FcPatternAdd(ptn, "family", &val, FcTrue); | 90 FcPatternAdd(ptn, "family", val, FcTrue); |
93 | 91 |
94 val.type = FcTypeInteger; | 92 val.type = FcTypeInteger; |
95 val.u.i = slant_map[slant]; | 93 val.u.i = slant_map[slant]; |
96 FcPatternAdd(ptn, "slant", &val, FcTrue); | 94 FcPatternAdd(ptn, "slant", val, FcTrue); |
97 | 95 |
98 val.type = FcTypeInteger; | 96 val.type = FcTypeInteger; |
99 val.u.i = weight; | 97 val.u.i = weight; |
100 FcPatternAdd(ptn, "weight", &val, FcTrue); | 98 FcPatternAdd(ptn, "weight", val, FcTrue); |
101 | 99 |
102 r = FcConfigSubstituteWithPat(cfg, ptn, NULL, FcMatchPattern); | 100 r = FcConfigSubstituteWithPat(cfg, ptn, NULL, FcMatchPattern); |
103 if(!r) | 101 if(!r) |
104 goto err; | 102 goto err; |
105 | 103 |
156 * user space of cairo surface. | 154 * user space of cairo surface. |
157 */ | 155 */ |
158 static | 156 static |
159 mb_scaled_font_t *make_scaled_font_face_matrix(mb_font_face_t *face, | 157 mb_scaled_font_t *make_scaled_font_face_matrix(mb_font_face_t *face, |
160 co_aix *matrix) { | 158 co_aix *matrix) { |
161 cairo_font_face_t *scaled_font; | 159 cairo_scaled_font_t *scaled_font; |
162 cairo_matrix_t font_matrix; | 160 cairo_matrix_t font_matrix; |
163 static cairo_matir_t id = { | 161 static cairo_matrix_t id = { |
164 1, 0, | 162 1, 0, |
165 0, 1, | 163 0, 1, |
166 0, 0 | 164 0, 0 |
167 }; | 165 }; |
168 static cairo_font_options_t *opt = NULL; | 166 static cairo_font_options_t *opt = NULL; |
270 txt_o->style_blks = NULL; | 268 txt_o->style_blks = NULL; |
271 txt_o->nblks = 0; | 269 txt_o->nblks = 0; |
272 txt_o->max_nblks = 0; | 270 txt_o->max_nblks = 0; |
273 txt_o->x = x; | 271 txt_o->x = x; |
274 txt_o->y = y; | 272 txt_o->y = y; |
275 txt_o->exts = NULL; | 273 txt_o->scaled_fonts = NULL; |
276 | 274 |
277 if(txt_o->txt == NULL) { | 275 if(txt_o->txt == NULL) { |
278 free(txt_o); | 276 free(txt_o); |
279 txt_o = NULL; | 277 txt_o = NULL; |
280 } | 278 } |
285 static | 283 static |
286 int compute_utf8_chars_sz(const char *txt, int n_chars) { | 284 int compute_utf8_chars_sz(const char *txt, int n_chars) { |
287 int i; | 285 int i; |
288 const char *p = txt; | 286 const char *p = txt; |
289 | 287 |
290 for(i = 0; i < n && *p; i++) { | 288 for(i = 0; i < n_chars && *p; i++) { |
291 if(*p++ & 0x80) | 289 if(*p++ & 0x80) |
292 continue; /* single byte */ | 290 continue; /* single byte */ |
293 /* multi-bytes */ | 291 /* multi-bytes */ |
294 while(*p && ((*p & 0xc0) == 0x80)) | 292 while(*p && ((*p & 0xc0) == 0x80)) |
295 p++; | 293 p++; |
296 } | 294 } |
297 if(i < n) | 295 if(i < n_chars) |
298 return ERR; | 296 return ERR; |
299 | 297 |
300 return p - txt; | 298 return p - txt; |
301 } | 299 } |
302 | 300 |
303 static | 301 static |
304 mb_scaled_font_t *make_scaled_font_face(sh_stext_t *txt_o, | 302 mb_scaled_font_t *make_scaled_font_face(sh_stext_t *txt_o, |
305 cairo_font_face_t *face, | 303 mb_font_face_t *face, |
306 co_aix shift_x, co_aix shift_y, | 304 co_aix shift_x, co_aix shift_y, |
307 co_aix font_sz) { | 305 co_aix font_sz) { |
308 co_aix matrix[6], scaled_matrix[6]; | 306 co_aix matrix[6], scaled_matrix[6]; |
309 co_aix *aggr; | 307 co_aix *aggr; |
310 mb_scaled_font_t *scaled; | 308 mb_scaled_font_t *scaled; |
359 * blocks before a style block. | 357 * blocks before a style block. |
360 */ | 358 */ |
361 static | 359 static |
362 void compute_styled_extents_n_scaled_font(sh_stext_t *txt_o) { | 360 void compute_styled_extents_n_scaled_font(sh_stext_t *txt_o) { |
363 mb_text_extents_t sub_extents; | 361 mb_text_extents_t sub_extents; |
364 mb_text_extents_t *extents; | 362 const mb_style_blk_t *blk; |
365 mb_style_blk_t *blk; | |
366 int blk_txt_len; | 363 int blk_txt_len; |
367 mb_scaled_font_t *scaled_font; | 364 mb_scaled_font_t **scaled_font; |
368 char *txt, saved; | 365 char *txt, saved; |
369 co_aix shift_x, shift_y; | 366 co_aix shift_x, shift_y; |
370 int i; | 367 int i; |
371 | 368 |
372 memset(&full_extents, sizeof(mb_text_extents_t), 0); | 369 memset(&txt_o->extents, sizeof(mb_text_extents_t), 0); |
373 | 370 |
374 blk = txt_o->style_blks; | 371 blk = txt_o->style_blks; |
375 scaled_font = txt_o->scaled_fonts; | 372 scaled_font = txt_o->scaled_fonts; |
376 txt = (char *)txt_o->txt; | 373 txt = (char *)txt_o->txt; |
377 extents = &txt_o->extents; | |
378 for(i = 0; i < txt_o->nblks; i++) { | 374 for(i = 0; i < txt_o->nblks; i++) { |
379 shift_x = txt_o->x + full_extents.x_adv; | 375 shift_x = txt_o->x + MBE_GET_X_ADV(&txt_o->extents); |
380 shift_y = txt_o->y + full_extents.y_adv; | 376 shift_y = txt_o->y + MBE_GET_Y_ADV(&txt_o->extents); |
381 | 377 |
382 *scaled_font = make_scaled_font_face(txt_o, blk->face, | 378 *scaled_font = make_scaled_font_face(txt_o, blk->face, |
383 shift_x, shift_y, font_sz); | 379 shift_x, shift_y, blk->font_sz); |
384 ASSERT(*scaled_font != NULL); | 380 ASSERT(*scaled_font != NULL); |
385 | 381 |
386 blk_txt_len = compute_utf8_chars_sz(txt, blk->n_chars); | 382 blk_txt_len = compute_utf8_chars_sz(txt, blk->n_chars); |
387 ASSERT(blk_txt_len != ERR); | 383 ASSERT(blk_txt_len != ERR); |
388 | 384 |
389 saved = txt[blk_txt_len]; | 385 saved = txt[blk_txt_len]; |
390 txt[blk_txt_len] = 0; | 386 txt[blk_txt_len] = 0; |
391 compute_text_extents(*scaled_font, txt, extents); | 387 compute_text_extents(*scaled_font, txt, &sub_extents); |
392 txt[blk_txt_len] = saved; | 388 txt[blk_txt_len] = saved; |
393 | 389 |
394 extent_extents(&txt_o->full_extents, extents); | 390 extent_extents(&txt_o->extents, &sub_extents); |
395 | 391 |
396 scaled_font++; | 392 scaled_font++; |
397 blk++; | 393 blk++; |
398 txt += blk_txt_len; | 394 txt += blk_txt_len; |
399 extents = &sub_extents; | |
400 } | 395 } |
401 } | 396 } |
402 | 397 |
403 /* | 398 /* |
404 * What we have to do in sh_stext_transform() is | 399 * What we have to do in sh_stext_transform() is |
427 | 422 |
428 ASSERT(txt_o != NULL); | 423 ASSERT(txt_o != NULL); |
429 ASSERT(txt != NULL); | 424 ASSERT(txt != NULL); |
430 | 425 |
431 sz = strlen(txt) + 1; | 426 sz = strlen(txt) + 1; |
432 new_txt = realloc(txt_o->txt, sz); | 427 new_txt = (char *)realloc((void *)txt_o->txt, sz); |
433 if(new_txt == NULL) | 428 if(new_txt == NULL) |
434 return ERR; | 429 return ERR; |
435 | 430 |
436 memcpy(new_txt, txt, sz); | 431 memcpy(new_txt, txt, sz); |
437 txt_o->txt = new_txt; | 432 txt_o->txt = new_txt; |
442 int sh_stext_set_style(shape_t *shape, | 437 int sh_stext_set_style(shape_t *shape, |
443 const mb_style_blk_t *blks, | 438 const mb_style_blk_t *blks, |
444 int nblks) { | 439 int nblks) { |
445 sh_stext_t *txt_o = (sh_stext_t *)shape; | 440 sh_stext_t *txt_o = (sh_stext_t *)shape; |
446 mb_style_blk_t *new_blks; | 441 mb_style_blk_t *new_blks; |
447 co_aix *new_exts; | |
448 int sz; | 442 int sz; |
449 | 443 |
450 ASSERT(txt_o != NULL); | 444 ASSERT(txt_o != NULL); |
451 ASSERT(nblks >= 0); | 445 ASSERT(nblks >= 0); |
452 | 446 |
453 if(nblks > txt_o->max_nblks) { | 447 if(nblks > txt_o->max_nblks) { |
454 sz = nblks * (sizeof(mb_style_blk_t) + sizeof(int)); | 448 sz = nblks * sizeof(mb_style_blk_t); |
455 new_blks = (mb_style_blk_t *)realloc(txt_o->style_blks, sz); | 449 new_blks = (mb_style_blk_t *)realloc((void *)txt_o->style_blks, sz); |
456 if(new_blks == NULL) | 450 if(new_blks == NULL) |
457 return ERR; | 451 return ERR; |
458 new_exts = (int *)(new_blks + nblks); | |
459 | 452 |
460 txt_o->style_blks = new_blks; | 453 txt_o->style_blks = new_blks; |
461 txt_o->exts = new_exts; | |
462 txt_o->max_nblks = nblks; | 454 txt_o->max_nblks = nblks; |
463 } | 455 } |
464 | 456 |
465 memcpy(txt_o->blks, blks, nblks * sizeof(mb_style_blk_t)); | 457 memcpy(txt_o->style_blks, blks, nblks * sizeof(mb_style_blk_t)); |
466 txt_o->nblks = nblks; | 458 txt_o->nblks = nblks; |
467 | 459 |
468 return OK; | 460 return OK; |
469 } | 461 } |
470 | 462 |
471 #endif /* SHAPE_STEXT */ | 463 #ifdef UNITTEST |
464 | |
465 static | |
466 void test_compute_text_extents(void) { | |
467 } | |
468 | |
469 #include <CUnit/Basic.h> | |
470 CU_pSuite get_stext_suite(void) { | |
471 CU_pSuite suite; | |
472 | |
473 suite = CU_add_suite("Suite_stext", NULL, NULL); | |
474 CU_ADD_TEST(suite, test_compute_text_extents); | |
475 | |
476 return suite; | |
477 } | |
478 | |
479 #endif /* UNITTEST */ |