emacs-bidi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [emacs-bidi] branch emacs-bidi is created


From: Eli Zaretskii
Subject: Re: [emacs-bidi] branch emacs-bidi is created
Date: Sun, 07 Mar 2004 16:36:38 +0200

> Date: Thu, 4 Mar 2004 09:07:22 +0900 (JST)
> From: Kenichi Handa <address@hidden>
> 
> I've just made a branch "emacs-bidi" and commited several
> changes including Eli's bidi code so that people other than
> I can start working on it.

Does this branch use the emacs-unicode as its base, or did you start
from CVS HEAD?

> But, although I can compile the code and start up Emacs,
> when I set the buffer local variable enable-bidi-display,
> Emacs crashes.   Eli, I need your help.

I didn't have time to check out the bidi branch, so the following is
based on code inspection.

> In the reseat_1 (in xdisp.c), I put this code.
> 
>   if (it->bidi_p)
>     {
>       bidi_init_it (pos.charpos, L2R, &it->bidi_it);
>       bidi_get_next_char_visually (&it->bidi_it);
> 
>       pos.charpos = it->bidi_it.charpos;
>       pos.bytepos = it->bidi_it.bytepos;
>       it->current.pos = it->position = pos;
>     }
> 
> But, as bidi_init_it doesn't set bidi_it->ch_len,
> bidi_get_next_char_visually sets it->bidi_it.bytepos to less
> than it->bidi_it.charpos.

Hmm, I knew this initialization thing will come back to haunt
me...  It's a bit tricky: the bidi iterator increments the position
(inside bidi_get_next_char_visually) _before_ it examines the next
character, so it needs to be initialized at the position one less than
where you want it to begin its iteration.  So I think you want to
change

>       bidi_init_it (pos.charpos, L2R, &it->bidi_it);

into

>       bidi_init_it (pos.charpos - 1, L2R, &it->bidi_it);

Btw, why did you use L2R as the second argument?  I think we should
use NEUTRAL_DIR instead, so that the code finds the paragraph
direction from the first strong directional character, as mandated by
UAX#9.

> bidi_init_it has this code:
> 
> bidi_init_it (int pos, bidi_dir_t dir, struct bidi_it *bidi_it)
> {
>   if (! bidi_initialized)
>     bidi_initialize ();
>   bidi_set_paragraph_end (bidi_it);
>   bidi_it->charpos = pos;
>   if (pos <= 0)
>     {
>       bidi_it->bytepos = bidi_it->charpos;
>       bidi_it->ch_len = 1;    /* so that incrementing bytepos works */
>     }
>   else
>     bidi_it->bytepos = CHAR_TO_BYTE (pos);
> 
> As POS is always greater than 0 when we are scanning a
> buffer, bidi_it->ch_len is not set.

I'm guessing that the else branch was never executed in my testing.
For completeness, I think setting bidi_it->ch_len in the else clause
like below will do:

      bidi_it->ch_len = CHAR_TO_BYTE(pos+1) - CHAR_TO_BYTE(pos);

In case this is too expensive, we could use the paradigm used by
xdisp.c to compute it->len:

      if (it->multibyte_p && !ASCII_BYTE_P (*p))
        {
          int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
                        - IT_BYTEPOS (*it));
          int c = string_char_and_length (p, maxlen, &it->len);
        }
      else
        it->len = 1;

(Btw, I think we sorely need an efficient macro for computing the
length, and only the length, of a multibyte character at a given
position in the buffer.)

Thanks again for making this happen.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]