Loading ...
Sorry, an error occurred while loading the content.

Double width character is displayed as broken.

Expand Messages
  • Yukihiro Nakadaira
    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,
    Message 1 of 4 , Oct 6, 2006
    • 0 Attachment
      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 - yukihiro.nakadaira@...
    • A.J.Mechelynck
      ... [...] ... [...] 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
      Message 2 of 4 , Oct 6, 2006
      • 0 Attachment
        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.
      • Yukihiro Nakadaira
        ... I m sorry. Other my personal code was mixed. I made a new diff from 7.0.118. Content is not changed. ... *************** ... * only redraw if the
        Message 3 of 4 , Oct 6, 2006
        • 0 Attachment
          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 - yukihiro.nakadaira@...
        • Bram Moolenaar
          ... Thanks for the clear explanation and the patch! I could reproduce the problem, I ll include the patch. -- Shift happens. -- Doppler /// Bram Moolenaar --
          Message 4 of 4 , Oct 7, 2006
          • 0 Attachment
            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 -- Bram@... -- 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 ///
          Your message has been successfully submitted and would be delivered to recipients shortly.