Double width character is displayed as broken.

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Double width character is displayed as broken.

Yukihiro Nakadaira-2
When using GUI and 'encoding' is utf-8, double width character is
sometimes displayed as broken.  I wrote a patch.  Please check the
following.

For example, please look this screenshot.

  http://yukihiro.nakadaira.googlepages.com/screenshot.png

There are single width character 'a' and multi-byte character 'A'.  And
'a' is highlighted.

After double width character 'B' is inserted, the second half of 'B' is
same value of 'A' (ScreenLinesUC is not cleared.  It keeps old value).

          offset |0|1|2|3|4|5|
                 |a| A |
                    |
                    | ScreenLinesUC is not cleared.
                    v
          offset |0|1|2|3|4|5|
   insert 'B' -> | B |a| A |
                    ^ ScreenLinesUC == 'A'

Then, insert NL.  Vim clear the line from 'a' to EOL.

                    +- ScreenLineUC == 'A'
                    v
          offset |0|1|2|3|4|5|
                 | B |a| A |
                     |-----------> to be cleared

If 'a' is highlighted, Vim redraw its previous character ('B').  But Vim
doesn't care about double width character.  Then, wrong offset is used.

  First, redraw the previous character with wrong offset.

                  +----- the first half of 'B'
                  | +--- ScreenLineUC[off - 1] == 'A' was drawn
                  | | +- off
                  v v v
          offset |0|1|2|3|4|5|
                 |B| A | A |
                     |-----------> to be cleared

  Second, clear the rest of line.

                  +----- the first half of 'B'
                  | +--- the first half of 'A'
                  | | +- the second half of 'A' was cleared
                  v v v
          offset |0|1|2|3|4|5|
                 |B|A|

  Result, double width character 'B' is displayed as broken.

         line 1: |0|1|2|3|4|5|
         line 2: |B|A|
         line 3: |a| A |




*** src/screen.c.orig Sat Oct  7 00:02:46 2006
--- src/screen.c Sat Oct  7 00:03:39 2006
***************
*** 5087,5100 ****
--- 5087,5133 ----
      * only redraw if the character wasn't already redrawn anyway.
      */
     if (gui.in_use && (col > startCol || !redraw_this)
+ #if 0
+   /* The following code works for enc_dbcs */
  # ifdef FEAT_MBYTE
     && enc_dbcs == 0
  # endif
+ #endif
        )
     {
  hl = ScreenAttrs[off_to];
  if (hl > HL_ALL || (hl & HL_BOLD))
+ {
+ # ifdef FEAT_MBYTE
+    int prev_cells = 1;
+
+    if (enc_utf8)
+ /* for utf-8, ScreenLines[char_offset + 1] == 0
+ * means that its width is 2. */
+ prev_cells = ScreenLines[off_to - 1] == 0 ? 2 : 1;
+    else if (enc_dbcs != 0)
+    {
+ /* find previous character by counting from
+ * first column and get its width. */
+ unsigned off = LineOffset[row];
+
+ while (off < off_to)
+ {
+    prev_cells = (*mb_off2cells)(off);
+    off += prev_cells;
+ }
+    }
+
+    if (enc_dbcs != 0 && prev_cells > 1)
+ screen_char_2(off_to - prev_cells,
+      row, col + coloff - prev_cells);
+    else
+ screen_char(off_to - prev_cells,
+    row, col + coloff - prev_cells);
+ # else
     screen_char(off_to - 1, row, col + coloff - 1);
+ # endif
+ }
     }
  #endif
     screen_fill(row, row + 1, col + coloff, clear_width + coloff,



--
Yukihiro Nakadaira - [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Double width character is displayed as broken.

A.J.Mechelynck
Yukihiro Nakadaira wrote:
> When using GUI and 'encoding' is utf-8, double width character is
> sometimes displayed as broken.  I wrote a patch.  Please check the
> following.
[...]
> *** src/screen.c.orig Sat Oct  7 00:02:46 2006
> --- src/screen.c Sat Oct  7 00:03:39 2006
> ***************
> *** 5087,5100 ****
> --- 5087,5133 ----
>       * only redraw if the character wasn't already redrawn anyway.
>       */
[...]


Against which version/patchlevel was this patch constructed? In the sources
for 7.0.119 I have a fuzz factor of -7 lines ("* only redraw" etc. is line 5080).


Best regards,
Tony.
Reply | Threaded
Open this post in threaded view
|

Re: Double width character is displayed as broken.

Yukihiro Nakadaira-2
A.J.Mechelynck wrote:
> Against which version/patchlevel was this patch constructed? In the sources
> for 7.0.119 I have a fuzz factor of -7 lines ("* only redraw" etc. is line 5080).

I'm sorry.  Other my personal code was mixed.  I made a new diff from
7.0.118.  Content is not changed.

*** src/screen.c.orig Sat Oct  7 05:30:19 2006
--- src/screen.c Sat Oct  7 05:30:19 2006
***************
*** 5080,5093 ****
--- 5080,5126 ----
      * only redraw if the character wasn't already redrawn anyway.
      */
     if (gui.in_use && (col > startCol || !redraw_this)
+ #if 0
+   /* The following code works for enc_dbcs */
  # ifdef FEAT_MBYTE
     && enc_dbcs == 0
  # endif
+ #endif
        )
     {
  hl = ScreenAttrs[off_to];
  if (hl > HL_ALL || (hl & HL_BOLD))
+ {
+ # ifdef FEAT_MBYTE
+    int prev_cells = 1;
+
+    if (enc_utf8)
+ /* for utf-8, ScreenLines[char_offset + 1] == 0
+ * means that its width is 2. */
+ prev_cells = ScreenLines[off_to - 1] == 0 ? 2 : 1;
+    else if (enc_dbcs != 0)
+    {
+ /* find previous character by counting from
+ * first column and get its width. */
+ unsigned off = LineOffset[row];
+
+ while (off < off_to)
+ {
+    prev_cells = (*mb_off2cells)(off);
+    off += prev_cells;
+ }
+    }
+
+    if (enc_dbcs != 0 && prev_cells > 1)
+ screen_char_2(off_to - prev_cells,
+      row, col + coloff - prev_cells);
+    else
+ screen_char(off_to - prev_cells,
+    row, col + coloff - prev_cells);
+ # else
     screen_char(off_to - 1, row, col + coloff - 1);
+ # endif
+ }
     }
  #endif
     screen_fill(row, row + 1, col + coloff, clear_width + coloff,



--
Yukihiro Nakadaira - [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Double width character is displayed as broken.

Bram Moolenaar
In reply to this post by Yukihiro Nakadaira-2

Yukihiro Nakadaira wrote:

> When using GUI and 'encoding' is utf-8, double width character is
> sometimes displayed as broken.  I wrote a patch.  Please check the
> following.
>
> For example, please look this screenshot.
>
>   http://yukihiro.nakadaira.googlepages.com/screenshot.png
>
> There are single width character 'a' and multi-byte character 'A'.  And
> 'a' is highlighted.
>
> After double width character 'B' is inserted, the second half of 'B' is
> same value of 'A' (ScreenLinesUC is not cleared.  It keeps old value).
>
>           offset |0|1|2|3|4|5|
>                  |a| A |
>                     |
>                     | ScreenLinesUC is not cleared.
>                     v
>           offset |0|1|2|3|4|5|
>    insert 'B' -> | B |a| A |
>                     ^ ScreenLinesUC == 'A'
>
> Then, insert NL.  Vim clear the line from 'a' to EOL.
>
>                     +- ScreenLineUC == 'A'
>                     v
>           offset |0|1|2|3|4|5|
>                  | B |a| A |
>                      |-----------> to be cleared
>
> If 'a' is highlighted, Vim redraw its previous character ('B').  But Vim
> doesn't care about double width character.  Then, wrong offset is used.
>
>   First, redraw the previous character with wrong offset.
>
>                   +----- the first half of 'B'
>                   | +--- ScreenLineUC[off - 1] == 'A' was drawn
>                   | | +- off
>                   v v v
>           offset |0|1|2|3|4|5|
>                  |B| A | A |
>                      |-----------> to be cleared
>
>   Second, clear the rest of line.
>
>                   +----- the first half of 'B'
>                   | +--- the first half of 'A'
>                   | | +- the second half of 'A' was cleared
>                   v v v
>           offset |0|1|2|3|4|5|
>                  |B|A|
>
>   Result, double width character 'B' is displayed as broken.
>
>          line 1: |0|1|2|3|4|5|
>          line 2: |B|A|
>          line 3: |a| A |

Thanks for the clear explanation and the patch!  I could reproduce the
problem, I'll include the patch.

--
Shift happens.
                -- Doppler

 /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///