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 */