summaryrefslogtreecommitdiff
path: root/src/lib/evas/common
diff options
context:
space:
mode:
authorDaniel Hirt <daniel.hirt@samsung.com>2016-07-13 11:40:36 +0000
committerDaniel Hirt <daniel.hirt@samsung.com>2016-07-14 12:22:44 +0000
commitef817f15f0eaec9704ec25d9468c2c8497a5bc13 (patch)
tree45ab138bdbee9c0ed5ac824d30577d0008798ac9 /src/lib/evas/common
parente8c396a6e2aae0f9da189930d0c55cd3d2500d58 (diff)
Evas font: fix width query for OT
Fixes T4068. Simply querying the last glyph to determine the width of the glyph sequence won't always work, as OT can have negative offsets (adjusts the placement of a specific glyph better). The solution is to calculate the "max width" of some sequence that will guarantee us proper width results. The worst solution would be to iterate on all the glyphs and sum up the max width. This is a bit impractical. Instead, we will inspect just the "cluster" of the last glyph, if one exists. This should have no performance impact on trivial cases, and very little impact on the others. @fix
Diffstat (limited to 'src/lib/evas/common')
-rw-r--r--src/lib/evas/common/evas_font_query.c93
1 files changed, 76 insertions, 17 deletions
diff --git a/src/lib/evas/common/evas_font_query.c b/src/lib/evas/common/evas_font_query.c
index f435b9b..cf977e9 100644
--- a/src/lib/evas/common/evas_font_query.c
+++ b/src/lib/evas/common/evas_font_query.c
@@ -314,6 +314,81 @@ evas_common_font_ascent_descent_get(RGBA_Font *fn, const Evas_Text_Props *text_p
314 if (descent) *descent = (desc < max_desc) ? desc : max_desc; 314 if (descent) *descent = (desc < max_desc) ? desc : max_desc;
315} 315}
316 316
317#ifdef OT_SUPPORT
318static inline Evas_Coord
319_evas_common_font_query_width_ot(const Evas_Text_Props *text_props)
320{
321 Evas_Coord ret_w = 0;
322
323 if (text_props->len > 0)
324 {
325 size_t off = text_props->start + text_props->len - 1;
326 const Evas_Font_Glyph_Info *glyph = text_props->info->glyph + off;
327 Evas_Font_OT_Info *ot = text_props->info->ot + off;
328 size_t cluster = ot->source_cluster;
329
330 do
331 {
332 Evas_Coord pen_x = (off > 0) ? glyph[-1].pen_after : 0;
333 Evas_Coord w = pen_x + glyph->x_bear + glyph->width +
334 EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(*ot));
335 if (w > ret_w)
336 {
337 ret_w = w;
338 }
339
340 glyph--;
341 ot--;
342 } while((off-- > text_props->start) && (ot->source_cluster == cluster));
343
344 if (text_props->start > 0)
345 {
346 ret_w -= text_props->info->glyph[text_props->start - 1].pen_after;
347 }
348 }
349
350 return ret_w;
351}
352#else
353static inline Evas_Coord
354_evas_common_font_query_width_regular(const Evas_Text_Props *text_props)
355{
356 Evas_Coord ret_w = 0;
357
358 if (text_props->len > 0)
359 {
360 const Evas_Font_Glyph_Info *last_glyph = text_props->info->glyph +
361 text_props->start + text_props->len - 1;
362
363 if (text_props->len > 1)
364 {
365 const Evas_Font_Glyph_Info *glyph = text_props->info->glyph +
366 text_props->start;
367
368 ret_w = last_glyph[-1].pen_after;
369 if (text_props->start > 0)
370 ret_w -= glyph[-1].pen_after;
371 }
372
373 ret_w += last_glyph->width + last_glyph->x_bear;
374 }
375
376 return ret_w;
377}
378#endif
379
380static inline Evas_Coord
381_evas_common_font_query_width(const Evas_Text_Props *text_props)
382{
383 Evas_Coord ret_w;
384#ifdef OT_SUPPORT
385 ret_w = _evas_common_font_query_width_ot(text_props);
386#else
387 ret_w = _evas_common_font_query_width_regular(text_props);
388#endif
389 return ret_w;
390}
391
317/** 392/**
318 * @internal 393 * @internal
319 * Calculate the size of the string (width and height). 394 * Calculate the size of the string (width and height).
@@ -333,24 +408,8 @@ evas_common_font_query_size(RGBA_Font *fn, const Evas_Text_Props *text_props, in
333 408
334 if (text_props->len > 0) 409 if (text_props->len > 0)
335 { 410 {
336 const Evas_Font_Glyph_Info *glyph = text_props->info->glyph + 411 ret_w = _evas_common_font_query_width(text_props);
337 text_props->start;
338 const Evas_Font_Glyph_Info *last_glyph = glyph;
339
340 if (text_props->len > 1)
341 {
342 last_glyph += text_props->len - 1;
343 ret_w = last_glyph[-1].pen_after;
344 if (text_props->start > 0)
345 ret_w -= glyph[-1].pen_after;
346 }
347#ifdef OT_SUPPORT
348 ret_w += EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(
349 text_props->info->ot[text_props->start + text_props->len - 1]));
350#endif
351 ret_w += last_glyph->width + last_glyph->x_bear;
352 } 412 }
353
354 if (w) *w = ret_w; 413 if (w) *w = ret_w;
355 if (h) *h = evas_common_font_max_ascent_get(fn) + evas_common_font_max_descent_get(fn); 414 if (h) *h = evas_common_font_max_ascent_get(fn) + evas_common_font_max_descent_get(fn);
356} 415}