comparison src/shape_stext.c @ 397:55f38c2cdb8f

Refactor function of computing text extents
author Thinker K.F. Li <thinker@branda.to>
date Thu, 11 Jun 2009 08:20:39 +0800
parents 7fe0b1ee92b6
children aee0f66b1154
comparison
equal deleted inserted replaced
396:7fe0b1ee92b6 397:55f38c2cdb8f
34 */ 34 */
35 typedef cairo_text_extents_t mb_text_extents_t; 35 typedef cairo_text_extents_t mb_text_extents_t;
36 36
37 #define MBE_GET_X_ADV(ext) ((ext)->x_advance) 37 #define MBE_GET_X_ADV(ext) ((ext)->x_advance)
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)
40 #define MBE_GET_Y_BEARING(ext) ((ext)->y_bearing)
39 #define MBE_GET_WIDTH(ext) ((ext)->width) 41 #define MBE_GET_WIDTH(ext) ((ext)->width)
40 #define MBE_GET_HEIGHT(ext) ((ext)->height) 42 #define MBE_GET_HEIGHT(ext) ((ext)->height)
41 43
42 /*! \brief Find out a font pattern. 44 /*! \brief Find out a font pattern.
43 * 45 *
129 * rotation. This function return a scaled font specified by a 131 * rotation. This function return a scaled font specified by a
130 * matrix that transform glyph from design space of the font to 132 * matrix that transform glyph from design space of the font to
131 * user space of cairo surface. 133 * user space of cairo surface.
132 */ 134 */
133 static 135 static
134 mb_scaled_font_t *get_cairo_scaled_font(mb_font_face_t *face, 136 mb_scaled_font_t *make_scaled_font_face_matrix(mb_font_face_t *face,
135 co_aix *matrix) { 137 co_aix *matrix) {
136 cairo_font_face_t *scaled_font; 138 cairo_font_face_t *scaled_font;
137 cairo_matrix_t font_matrix; 139 cairo_matrix_t font_matrix;
138 static cairo_matir_t id = { 140 static cairo_matir_t id = {
139 1, 0, 141 1, 0,
140 0, 1, 142 0, 1,
162 164
163 return (mb_scaled_font_t *)scaled_font; 165 return (mb_scaled_font_t *)scaled_font;
164 } 166 }
165 167
166 static 168 static
167 void free_scaled_font(mb_scaled_font_t *scaled_font) { 169 void scaled_font_free(mb_scaled_font_t *scaled_font) {
168 cairo_scaled_font_destroy((cairo_scaled_font_t *)scaled_font); 170 cairo_scaled_font_destroy((cairo_scaled_font_t *)scaled_font);
169 } 171 }
170 172
171 static 173 static
172 void text_extents(mb_scaled_font_t *scaled_font, const char *txt, 174 void compute_text_extents(mb_scaled_font_t *scaled_font, const char *txt,
173 mb_text_extents_t *extents) { 175 mb_text_extents_t *extents) {
174 cairo_scaled_font_text_extents((cairo_scaled_font_t *)scaled_font, 176 cairo_scaled_font_text_extents((cairo_scaled_font_t *)scaled_font,
175 txt, 177 txt,
176 (cairo_text_extents_t *)extents); 178 (cairo_text_extents_t *)extents);
177 } 179 }
178 180
273 275
274 return p - txt; 276 return p - txt;
275 } 277 }
276 278
277 static 279 static
278 void compute_text_extents(char *txt, int txt_len, 280 mb_scaled_font_t *make_scaled_font_face(sh_stext_t *txt_o,
279 cairo_scaled_font_t *scaled_font,
280 cairo_text_extents_t *extents) {
281 char saved;
282
283 saved = txt[txt_len];
284 txt[txt_len] = 0;
285 cairo_scaled_font_text_extents(scaled_font, txt, extents);
286 txt[txt_len] = saved;
287 }
288
289 static
290 cairo_scaled_font_t *make_scaled_font_face(sh_stext_t *txt_o,
291 cairo_font_face_t *face, 281 cairo_font_face_t *face,
292 co_aix shift_x, co_aix shift_y, 282 co_aix shift_x, co_aix shift_y,
293 co_aix font_sz) { 283 co_aix font_sz) {
294 cairo_matrix_t cmtx; 284 co_aix matrix[6], scaled_matrix[6];
295 static cairo_matrix_t cid; 285 co_aix *aggr;
296 static cairo_font_options_t *fopt = NULL; 286 mb_scaled_font_t *scaled;
297 co_aix *matrix; 287
298 cairo_scaled_font_t *scaled; 288 aggr = sh_get_aggr_matrix((shape_t *)txt_o);
289 matrix[0] = font_sz;
290 matrix[1] = 0;
291 matrix[2] = shift_x;
292 matrix[3] = 0;
293 matrix[4] = font_sz;
294 matrix[5] += shift_y;
295 matrix_mul(aggr, matrix, scaled_matrix);
296
297 scaled = make_scaled_font_face_matrix(face, scaled_matrix);
298
299 return scaled;
300 }
301
302 static
303 void compute_styled_extents(sh_stext_t *txt_o) {
304 mb_text_extents_t sub_extents, full_extents;
305 mb_text_extents_t *ext;
306 mb_style_blk_t *blk;
307 int blk_txt_len;
308 mb_scaled_font_t *scaled_font;
309 char *txt, saved;
310 co_aix shift_x, shift_y;
299 int i; 311 int i;
300 312
301 if(fopt == NULL) { 313 memset(&full_extents, sizeof(mb_text_extents_t), 0);
302 cairo_matrix_init_identify(&cid); 314
303 fopt = cairo_font_options_create();
304 if(fopt == NULL)
305 return NULL;
306 }
307
308 matrix = sh_get_aggr_matrix((shape_t *)txt_o);
309 i = 0;
310 cmtx.xx = matrix[i++];
311 cmtx.xy = matrix[i++];
312 cmtx.x0 = matrix[i++] + shift_x;
313 cmtx.yx = matrix[i++];
314 cmtx.yy = matrix[i++];
315 cmtx.y0 = matrix[i] + shift_y;
316
317 scaled = cairo_scaled_font_create(face, &cmtx, &cid, fopt);
318
319 return scaled;
320 }
321
322 static
323 void compute_extents(sh_stext_t *txt_o) {
324 co_aix adv_x, adv_y;
325 cairo_text_extents_t extents;
326 mb_style_blk_t *blk;
327 cairo_scaled_font_t *scaled_font;
328 char *txt;
329 co_aix shift_x, shift_y;
330 int blk_txt_len;
331 int i;
332
333 adv_x = adv_y = 0;
334 blk = txt_o->style_blks; 315 blk = txt_o->style_blks;
335 scaled_font = txt_o->scaled_fonts; 316 scaled_font = txt_o->scaled_fonts;
336 txt = (char *)txt_o->txt; 317 txt = (char *)txt_o->txt;
337 shift_x = txt_o->x; 318 ext = &full_extents;
338 shift_y = txt_o->y;
339 for(i = 0; i < txt_o->nblks; i++) { 319 for(i = 0; i < txt_o->nblks; i++) {
340 *scaled_font = make_scaled_fonts(txt_o, blk->face, 320 shift_x = txt_o->x + full_extents.x_adv;
341 shift_x, shift_y, font_sz); 321 shift_y = txt_o->y + full_extents.y_adv;
322
323 *scaled_font = make_scaled_font_face(txt_o, blk->face,
324 shift_x, shift_y, font_sz);
342 ASSERT(*scaled_font != NULL); 325 ASSERT(*scaled_font != NULL);
343 326
344 blk_txt_len = compute_utf8_chars_sz(txt, blk->n_chars); 327 blk_txt_len = compute_utf8_chars_sz(txt, blk->n_chars);
345 ASSERT(blk_txt_len != ERR); 328 ASSERT(blk_txt_len != ERR);
346 329
347 compute_text_extents(txt, blk_txt_len, *scaled_font, &extents); 330 saved = txt[blk_txt_len];
348 adv_x += extents.x_advance; 331 txt[blk_txt_len] = 0;
349 adv_y += extents.y_advance; 332 compute_text_extents(scaled_font, txt, &extents);
333 txt[blk_txt_len] = saved;
334
335 adv_x += MBE_GET_X_ADV(&extents);
336 adv_y += MBE_GET_Y_ADV(&extents);
350 337
351 scaled_font++; 338 scaled_font++;
352 blk++; 339 blk++;
353 txt += blk_txt_len; 340 txt += blk_txt_len;
341 ext = &sub_extents;
354 } 342 }
355 } 343 }
356 344
357 /* 345 /*
358 * What we have to do in sh_stext_transform() is 346 * What we have to do in sh_stext_transform() is