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