Mercurial > MadButterfly
comparison src/shape_stext.c @ 403:aee0f66b1154
Compute extents of a styled text
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Tue, 16 Jun 2009 23:01:38 +0800 |
parents | 55f38c2cdb8f |
children | 92a459a1c5aa |
comparison
equal
deleted
inserted
replaced
397:55f38c2cdb8f | 403:aee0f66b1154 |
---|---|
38 #define MBE_GET_Y_ADV(ext) ((ext)->y_advance) | 38 #define MBE_GET_Y_ADV(ext) ((ext)->y_advance) |
39 #define MBE_GET_X_BEARING(ext) ((ext)->x_bearing) | 39 #define MBE_GET_X_BEARING(ext) ((ext)->x_bearing) |
40 #define MBE_GET_Y_BEARING(ext) ((ext)->y_bearing) | 40 #define MBE_GET_Y_BEARING(ext) ((ext)->y_bearing) |
41 #define MBE_GET_WIDTH(ext) ((ext)->width) | 41 #define MBE_GET_WIDTH(ext) ((ext)->width) |
42 #define MBE_GET_HEIGHT(ext) ((ext)->height) | 42 #define MBE_GET_HEIGHT(ext) ((ext)->height) |
43 #define MBE_SET_X_ADV(ext, v) do { ((ext)->x_advance) = v; } while(0) | |
44 #define MBE_SET_Y_ADV(ext, v) do { ((ext)->y_advance) = v; } while(0) | |
45 #define MBE_SET_X_BEARING(ext, v) do { ((ext)->x_bearing) = v; } while(0) | |
46 #define MBE_SET_Y_BEARING(ext, v) do { ((ext)->y_bearing) = v; } while(0) | |
47 #define MBE_SET_WIDTH(ext, v) do { ((ext)->width) = v; } while(0) | |
48 #define MBE_SET_HEIGHT(ext, v) do { ((ext)->height) = v; } while(0) | |
43 | 49 |
44 /*! \brief Find out a font pattern. | 50 /*! \brief Find out a font pattern. |
45 * | 51 * |
46 * This function use fontconfig to decide a font file in pattern. It can | 52 * This function use fontconfig to decide a font file in pattern. It can |
47 * replaced by other mechanism if you think it is not what you want. | 53 * replaced by other mechanism if you think it is not what you want. |
225 const mb_style_blk_t *style_blks; /*!< \brief Style of text */ | 231 const mb_style_blk_t *style_blks; /*!< \brief Style of text */ |
226 int nblks; /*!< \brief Number of style blocks */ | 232 int nblks; /*!< \brief Number of style blocks */ |
227 int max_nblks; | 233 int max_nblks; |
228 co_aix x, y; | 234 co_aix x, y; |
229 mb_scaled_font_t **scaled_fonts; | 235 mb_scaled_font_t **scaled_fonts; |
236 mb_text_extents_t extents; | |
230 } sh_stext_t; | 237 } sh_stext_t; |
231 | 238 |
232 shape_t *rdman_shape_stext_new(redraw_man_t *rdman, co_aix x, co_aix y, | 239 shape_t *rdman_shape_stext_new(redraw_man_t *rdman, co_aix x, co_aix y, |
233 const char *txt) { | 240 const char *txt) { |
234 sh_stext_t *txt_o; | 241 sh_stext_t *txt_o; |
297 scaled = make_scaled_font_face_matrix(face, scaled_matrix); | 304 scaled = make_scaled_font_face_matrix(face, scaled_matrix); |
298 | 305 |
299 return scaled; | 306 return scaled; |
300 } | 307 } |
301 | 308 |
302 static | 309 /*! \brief Extend an extents from another sub-extents. |
303 void compute_styled_extents(sh_stext_t *txt_o) { | 310 * |
304 mb_text_extents_t sub_extents, full_extents; | 311 * A styled text is styled by several styled blocks, so extents of |
305 mb_text_extents_t *ext; | 312 * blocks should be computed separated, collected, and aggreagated |
313 * into a full extents. | |
314 */ | |
315 static | |
316 void extent_extents(mb_text_extents_t *full, mb_text_extents_t *sub) { | |
317 co_aix f_rbx, f_rby; | |
318 co_aix s_rbx, s_rby; | |
319 | |
320 f_rbx = MBE_GET_X_BEARING(full) + MBE_GET_WIDTH(full); | |
321 f_rby = MBE_GET_Y_BEARING(full) + MBE_GET_HEIGHT(full); | |
322 s_rbx = MBE_GET_X_BEARING(sub) + MBE_GET_WIDTH(sub); | |
323 s_rby = MBE_GET_Y_BEARING(sub) + MBE_GET_HEIGHT(sub); | |
324 | |
325 /* set bearing */ | |
326 if(MBE_GET_X_BEARING(full) > MBE_GET_X_BEARING(sub)) | |
327 MBE_SET_X_BEARING(full, MBE_GET_X_BEARING(sub)); | |
328 if(MBE_GET_Y_BEARING(full) > MBE_GET_Y_BEARING(sub)) | |
329 MBE_SET_Y_BEARING(full, MBE_GET_Y_BEARING(sub)); | |
330 | |
331 /* set width/height */ | |
332 if(f_rbx < s_rbx) | |
333 MBE_SET_WIDTH(full, s_rbx - MBE_GET_X_BEARING(full)); | |
334 if(f_rby < s_rby) | |
335 MBE_SET_HEIGHT(full, s_rby - MBE_GET_Y_BEARING(full)); | |
336 } | |
337 | |
338 /*! \brief Compute extents of a stext object according style blocks. | |
339 * | |
340 * It create scaled fonts for style blocks, compute their extents, | |
341 * and compute where they should be draw acoording advance of style | |
342 * blocks before a style block. | |
343 */ | |
344 static | |
345 void compute_styled_extents_n_scaled_font(sh_stext_t *txt_o) { | |
346 mb_text_extents_t sub_extents; | |
347 mb_text_extents_t *extents; | |
306 mb_style_blk_t *blk; | 348 mb_style_blk_t *blk; |
307 int blk_txt_len; | 349 int blk_txt_len; |
308 mb_scaled_font_t *scaled_font; | 350 mb_scaled_font_t *scaled_font; |
309 char *txt, saved; | 351 char *txt, saved; |
310 co_aix shift_x, shift_y; | 352 co_aix shift_x, shift_y; |
313 memset(&full_extents, sizeof(mb_text_extents_t), 0); | 355 memset(&full_extents, sizeof(mb_text_extents_t), 0); |
314 | 356 |
315 blk = txt_o->style_blks; | 357 blk = txt_o->style_blks; |
316 scaled_font = txt_o->scaled_fonts; | 358 scaled_font = txt_o->scaled_fonts; |
317 txt = (char *)txt_o->txt; | 359 txt = (char *)txt_o->txt; |
318 ext = &full_extents; | 360 extents = &txt_o->extents; |
319 for(i = 0; i < txt_o->nblks; i++) { | 361 for(i = 0; i < txt_o->nblks; i++) { |
320 shift_x = txt_o->x + full_extents.x_adv; | 362 shift_x = txt_o->x + full_extents.x_adv; |
321 shift_y = txt_o->y + full_extents.y_adv; | 363 shift_y = txt_o->y + full_extents.y_adv; |
322 | 364 |
323 *scaled_font = make_scaled_font_face(txt_o, blk->face, | 365 *scaled_font = make_scaled_font_face(txt_o, blk->face, |
327 blk_txt_len = compute_utf8_chars_sz(txt, blk->n_chars); | 369 blk_txt_len = compute_utf8_chars_sz(txt, blk->n_chars); |
328 ASSERT(blk_txt_len != ERR); | 370 ASSERT(blk_txt_len != ERR); |
329 | 371 |
330 saved = txt[blk_txt_len]; | 372 saved = txt[blk_txt_len]; |
331 txt[blk_txt_len] = 0; | 373 txt[blk_txt_len] = 0; |
332 compute_text_extents(scaled_font, txt, &extents); | 374 compute_text_extents(*scaled_font, txt, extents); |
333 txt[blk_txt_len] = saved; | 375 txt[blk_txt_len] = saved; |
334 | 376 |
335 adv_x += MBE_GET_X_ADV(&extents); | 377 extent_extents(&txt_o->full_extents, extents); |
336 adv_y += MBE_GET_Y_ADV(&extents); | 378 |
337 | |
338 scaled_font++; | 379 scaled_font++; |
339 blk++; | 380 blk++; |
340 txt += blk_txt_len; | 381 txt += blk_txt_len; |
341 ext = &sub_extents; | 382 extents = &sub_extents; |
342 } | 383 } |
343 } | 384 } |
344 | 385 |
345 /* | 386 /* |
346 * What we have to do in sh_stext_transform() is | 387 * What we have to do in sh_stext_transform() is |
351 */ | 392 */ |
352 void sh_stext_transform(shape_t *shape) { | 393 void sh_stext_transform(shape_t *shape) { |
353 sh_stext_t *txt_o = (sh_stext_t *)shape; | 394 sh_stext_t *txt_o = (sh_stext_t *)shape; |
354 | 395 |
355 ASSERT(txt_o != NULL); | 396 ASSERT(txt_o != NULL); |
397 compute_styled_extents_n_scaled_font(txt_o); | |
356 } | 398 } |
357 | 399 |
358 void sh_stext_draw(shape_t *shape, cairo_t *cr) { | 400 void sh_stext_draw(shape_t *shape, cairo_t *cr) { |
359 sh_stext_t *txt_o = (sh_stext_t *)shape; | 401 sh_stext_t *txt_o = (sh_stext_t *)shape; |
360 | 402 |