Fix negative x bearing issue 94/304094/6 accepted/tizen/unified/20240124.163221 accepted/tizen/unified/x/20240205.064044
authorBowon Ryu <bowon.ryu@samsung.com>
Wed, 10 Jan 2024 04:22:09 +0000 (13:22 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Mon, 15 Jan 2024 03:08:01 +0000 (12:08 +0900)
This patch calculates the x offset of the line when the x bearing is negative
and applies it in the line position and size
to avoids unintentional truncation of glyphs based on the glyph properties.

Change-Id: Iafa7a18822de4bc6e952c2182b0c692907064ab0
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
src/lib/evas/canvas/evas_object_textblock.c

index 3357eeb..d3d9b5c 100644 (file)
@@ -3927,6 +3927,7 @@ struct _Ctxt
    /* TIZEN_ONLY(20170201): Fix RTL + LTR word wrap issue caused by wrong line start pos */
    int ln_min_text_pos;
    /* END */
+   int ln_x_offset;
    double align, valign;
    struct {
         int                              l, r, t, b;
@@ -4111,6 +4112,7 @@ _layout_line_new(Ctxt *c, Evas_Object_Textblock_Format *fmt)
    c->marginr = fmt->margin.r;
    c->par->lines = (Evas_Object_Textblock_Line *)eina_inlist_append(EINA_INLIST_GET(c->par->lines), EINA_INLIST_GET(c->ln));
    c->x = 0;
+   c->ln_x_offset = 0;
    c->ascent = c->descent = 0;
    c->maxascent = c->maxdescent = 0;
    c->ln->line_no = -1;
@@ -4909,6 +4911,16 @@ typedef struct _Evas_Textblock_Obstacle_Info
    Evas_Coord obs_preadv;
 } Evas_Textblock_Obstacle_Info;
 
+static int
+_layout_item_inset_get(Evas_Object_Protected_Data *obj, Evas_Object_Textblock_Item *it)
+{
+   if (!it || !it->format || !it->format->font.font)
+     {
+        return 0;
+     }
+   return ENFN->font_inset_get(ENC, it->format->font.font, &_ITEM_TEXT(it)->text_props);
+}
+
 /**
  * @internal
  * Order the items in the line, update it's properties and update it's
@@ -4967,6 +4979,10 @@ _layout_line_finalize(Ctxt *c, Evas_Object_Textblock_Format *fmt)
                 c->maxascent = maxasc;
              if (maxdesc > c->maxdescent)
                 c->maxdescent = maxdesc;
+
+             Evas_Coord inset = _layout_item_inset_get(c->evas_o, it);
+             if (c->ln_x_offset + x + inset < 0)
+                c->ln_x_offset = c->ln_x_offset - (c->ln_x_offset + x + inset);
           }
 
 loop_advance:
@@ -5066,13 +5082,15 @@ loop_advance:
         c->line_no++;
         c->y += c->ascent + c->descent;
      }
+
+   c->ln->w += c->ln_x_offset;
    if (c->w >= 0)
      {
         /* c->o->style_pad.r is already included in the line width, so it's
          * not used in this calculation. . */
         c->ln->x = c->marginl + c->o->style_pad.l +
            ((c->w - c->ln->w - c->o->style_pad.l - c->o->style_pad.r -
-             c->marginl - c->marginr) * _layout_line_align_get(c));
+             c->marginl - c->marginr) * _layout_line_align_get(c)) + c->ln_x_offset;
      }
    else
      {
@@ -5987,8 +6005,7 @@ _layout_get_charwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
         if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
            wrap = 0;
         else
-           wrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it),
-                w, from_x, 0);
+           wrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), w - c->ln_x_offset, from_x, -c->ln_x_offset);
 
         if (wrap < 0)
            return -1;
@@ -6200,7 +6217,8 @@ _layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt,
         if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
            swrap = 0;
         else
-           swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), w, from_x, 0);
+           swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), w - c->ln_x_offset, from_x, -c->ln_x_offset);
+
         /* Avoiding too small textblocks to even contain one char.
          * FIXME: This can cause breaking inside ligatures. */
 
@@ -6388,7 +6406,7 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
     */
    ellip_w = EVAS_TEXTBLOCK_TEXT_ITEM_SIZE(ellip_ti);
    /* END */
-   temp_w -= ellip_w;
+   temp_w -= ellip_w + c->ln_x_offset;
 
    /* If there is no enough space for ellipsis item, remove all of items */
    if (temp_w <= 0)
@@ -6410,7 +6428,7 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
              ti = _ITEM_TEXT(last_it);
 
              wrap = _layout_text_cutoff_get(c, last_it->format, ti,
-                  temp_w, c->x, ellip_ti->parent.w);
+                  temp_w, c->x, ellip_ti->parent.w - c->ln_x_offset);
 
              if ((wrap > 0) && !IS_AT_END(ti, (size_t) wrap))
                {
@@ -6820,6 +6838,8 @@ _layout_par(Ctxt *c)
    Evas_Textblock_Obstacle *obs = NULL;
    c->par->last_fw = 0;
    it = NULL;
+   c->ln_x_offset = 0;
+
    for (i = c->par->logical_items ; i ; )
      {
         Evas_Coord prevdescent = 0, prevascent = 0;
@@ -6939,6 +6959,15 @@ _layout_par(Ctxt *c)
            or we already found a wrap point. */
         itw = it->w;
 
+        if (it->type != EVAS_TEXTBLOCK_ITEM_FORMAT)
+          {
+             Evas_Coord inset = _layout_item_inset_get(c->evas_o, it);
+             if (c->ln_x_offset + it->x + inset < 0)
+                c->ln_x_offset = c->ln_x_offset - (c->ln_x_offset + it->x + inset);
+          }
+
+        needed_w += c->ln_x_offset;
+
 /* TIZEN_ONLY(20160517): Calculate exact width for current item
         if ((c->w >= 0) &&
               (obs ||
@@ -7889,6 +7918,7 @@ _layout_setup(Ctxt *c, const Eo *eo_obj, Evas_Coord w, Evas_Coord h)
    c->format_stack = NULL;
    c->fmt = NULL;
    c->x = c->y = 0;
+   c->ln_x_offset = 0;
    c->w = w;
    c->h = h;
    c->wmax = c->hmax = 0;
@@ -15021,6 +15051,7 @@ _size_native_calc_line_finalize(const Evas_Object *eo_obj,
 
    it = eina_list_data_get(items);
    *w = 0;
+   Evas_Coord ln_x_offset = 0;
 
    if (it)
      {
@@ -15080,6 +15111,10 @@ _size_native_calc_line_finalize(const Evas_Object *eo_obj,
                 *ascent = maxasc;
              if (maxdesc > *descent)
                 *descent = maxdesc;
+
+             Evas_Coord inset = _layout_item_inset_get(obj, it);
+             if (ln_x_offset + it->x + inset < 0)
+                ln_x_offset = ln_x_offset - (ln_x_offset + it->x + inset);
           }
 
 loop_advance:
@@ -15103,6 +15138,8 @@ loop_advance:
    if (last_it && (last_it->w > last_it->adv))
      *w += last_it->w - last_it->adv;
    /* END */
+
+   *w += ln_x_offset;
 }
 
 /* FIXME: doc */