case RLE:
case RLO:
case PDF:
- return default_type;
- /* FIXME: The isolate controls are treated as BN until we add
- support for UBA v6.3. */
case LRI:
case RLI:
case FSI:
case PDI:
- return WEAK_BN;
+ return default_type;
default:
if (override == L2R)
return STRONG_L;
case WEAK_CS:
case WEAK_NSM:
case WEAK_BN:
- /* FIXME */
- case LRI:
- case RLI:
- case FSI:
- case PDI:
return WEAK;
case NEUTRAL_B:
case NEUTRAL_S:
case RLE:
case RLO:
case PDF:
-#if 0
- /* FIXME: This awaits implementation of isolate support. */
case LRI:
case RLI:
case FSI:
case PDI:
-#endif
return EXPLICIT_FORMATTING;
default:
emacs_abort ();
int level, bidi_dir_t override)
{
bidi_it->stack_idx++;
- eassert (bidi_it->stack_idx < BIDI_MAXLEVEL);
+ eassert (bidi_it->stack_idx < BIDI_MAXDEPTH+2+1);
bidi_it->level_stack[bidi_it->stack_idx].level = level;
bidi_it->level_stack[bidi_it->stack_idx].override = override;
}
return ch;
}
+/* Like bidi_fetch_char, but ignore any text between an isolate
+ initiator and its matching PDI or, if it has no matching PDI, the
+ end of the paragraph. If isolates were skipped, CH_LEN and NCHARS
+ are set to the number of bytes and characters between BYTEPOS/CHARPOS
+ and the character that was fetched after skipping the isolates. */
+static int
+bidi_fetch_char_skip_isolates (ptrdiff_t charpos, ptrdiff_t bytepos,
+ ptrdiff_t *disp_pos, int *disp_prop,
+ struct bidi_string_data *string,
+ struct window *w, bool frame_window_p,
+ ptrdiff_t *ch_len, ptrdiff_t *nchars)
+{
+ ptrdiff_t orig_charpos = charpos, orig_bytepos = bytepos;
+ int ch = bidi_fetch_char (charpos, bytepos, disp_pos, disp_prop, string, w,
+ frame_window_p, ch_len, nchars);
+ bidi_type_t ch_type = bidi_get_type (ch, NEUTRAL_DIR);
+ ptrdiff_t level = 0;
+
+ if (ch_type == LRI || ch_type == RLI || ch_type == FSI)
+ {
+ level++;
+ while (level > 0 && ch_type != NEUTRAL_B)
+ {
+ charpos += *nchars;
+ bytepos += *ch_len;
+ ch = bidi_fetch_char (charpos, bytepos, disp_pos, disp_prop, string,
+ w, frame_window_p, ch_len, nchars);
+ ch_type = bidi_get_type (ch, NEUTRAL_DIR);
+ /* A Note to P2 says to ignore max_depth limit. */
+ if (ch_type == LRI || ch_type == RLI || ch_type == FSI)
+ level++;
+ else if (ch_type == PDI)
+ level--;
+ }
+ }
+
+ /* Communicate to the caller how much did we skip, so it could get
+ past the last character position we examined. */
+ *nchars += charpos - orig_charpos;
+ *ch_len += bytepos - orig_bytepos;
+ return ch;
+}
+
+
\f
/***********************************************************************
Determining paragraph direction
bytepos = pstartbyte;
if (!string_p)
pos = BYTE_TO_CHAR (bytepos);
- ch = bidi_fetch_char (pos, bytepos, &disp_pos, &disp_prop,
- &bidi_it->string, bidi_it->w,
- bidi_it->frame_window_p, &ch_len, &nchars);
+ ch = bidi_fetch_char_skip_isolates (pos, bytepos, &disp_pos, &disp_prop,
+ &bidi_it->string, bidi_it->w,
+ bidi_it->frame_window_p, &ch_len,
+ &nchars);
type = bidi_get_type (ch, NEUTRAL_DIR);
pos1 = pos;
for (pos += nchars, bytepos += ch_len;
- ((bidi_get_category (type) != STRONG)
- || (bidi_ignore_explicit_marks_for_paragraph_level
- && (type == RLE || type == RLO
- || type == LRE || type == LRO)))
+ bidi_get_category (type) != STRONG
/* Stop when searched too far into an abnormally large
paragraph full of weak or neutral characters. */
&& pos - pos1 < MAX_STRONG_CHAR_SEARCH;
&& bidi_at_paragraph_end (pos, bytepos) >= -1)
break;
/* Fetch next character and advance to get past it. */
- ch = bidi_fetch_char (pos, bytepos, &disp_pos,
- &disp_prop, &bidi_it->string, bidi_it->w,
- bidi_it->frame_window_p, &ch_len, &nchars);
+ ch = bidi_fetch_char_skip_isolates (pos, bytepos, &disp_pos,
+ &disp_prop, &bidi_it->string,
+ bidi_it->w,
+ bidi_it->frame_window_p,
+ &ch_len, &nchars);
pos += nchars;
bytepos += ch_len;
}
- if ((type == STRONG_R || type == STRONG_AL) /* P3 */
- || (!bidi_ignore_explicit_marks_for_paragraph_level
- && (type == RLO || type == RLE)))
+ if (type == STRONG_R || type == STRONG_AL) /* P3 */
bidi_it->paragraph_dir = R2L;
- else if (type == STRONG_L
- || (!bidi_ignore_explicit_marks_for_paragraph_level
- && (type == LRO || type == LRE)))
+ else if (type == STRONG_L)
bidi_it->paragraph_dir = L2R;
if (!string_p
&& no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR)
type = WEAK_BN; /* X9/Retaining */
if (bidi_it->ignore_bn_limit <= -1)
{
- if (current_level <= BIDI_MAXLEVEL - 4)
+ if (current_level < BIDI_MAXDEPTH)
{
/* Compute the least odd embedding level greater than
the current level. */
override = NEUTRAL_DIR;
else
override = R2L;
- if (current_level == BIDI_MAXLEVEL - 4)
+ if (current_level == BIDI_MAXDEPTH - 1)
bidi_it->invalid_rl_levels = 0;
bidi_push_embedding_level (bidi_it, new_level, override);
}
type = WEAK_BN; /* X9/Retaining */
if (bidi_it->ignore_bn_limit <= -1)
{
- if (current_level <= BIDI_MAXLEVEL - 5)
+ if (current_level < BIDI_MAXDEPTH - 1)
{
/* Compute the least even embedding level greater than
the current level. */
do {
ch = bidi_fetch_char (cpos += nc, bpos += clen, &disp_pos, &dpp, &bs,
bidi_it->w, fwp, &clen, &nc);
- if (ch == '\n' || ch == BIDI_EOB)
- chtype = NEUTRAL_B;
- else
- chtype = bidi_get_type (ch, NEUTRAL_DIR);
+ chtype = bidi_get_type (ch, NEUTRAL_DIR);
} while (chtype == NEUTRAL_WS || chtype == WEAK_BN
|| bidi_explicit_dir_char (ch)); /* L1/Retaining */
bidi_it->next_for_ws.type = chtype;
extern int face_change_count;
/* For reordering of bidirectional text. */
-#define BIDI_MAXLEVEL 64
+
+/* UAX#9's max_depth value. */
+#define BIDI_MAXDEPTH 125
/* Data type for describing the bidirectional character types. The
first 7 must be at the beginning, because they are the only values
bidi_type_t orig_type; /* type as we found it in the buffer */
};
-/* Data type for keeping track of saved embedding levels and override
- status information. */
+/* Data type for keeping track of saved embedding levels, override
+ status, and isolate status information. */
struct bidi_stack {
- int level;
+ char level;
+ bool isolate_status;
bidi_dir_t override;
};
resolving weak and neutral types */
bidi_type_t type_after_w1; /* original type, after overrides and W1 */
bidi_type_t orig_type; /* original type, as found in the buffer */
- int resolved_level; /* final resolved level of this character */
- int invalid_levels; /* how many PDFs to ignore */
- int invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */
+ char resolved_level; /* final resolved level of this character */
+ char isolate_level; /* count of isolate initiators unmatched by PDI */
+ ptrdiff_t invalid_levels; /* how many PDFs to ignore */
+ ptrdiff_t invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */
+ ptrdiff_t invalid_isolates; /* how many PDIs to ignore */
struct bidi_saved_info prev; /* info about previous character */
struct bidi_saved_info last_strong; /* last-seen strong directional char */
struct bidi_saved_info next_for_neutral; /* surrounding characters for... */
/* Note: Everything from here on is not copied/saved when the bidi
iterator state is saved, pushed, or popped. So only put here
stuff that is not part of the bidi iterator's state! */
- struct bidi_stack level_stack[BIDI_MAXLEVEL]; /* stack of embedding levels */
+ struct bidi_stack level_stack[BIDI_MAXDEPTH+2+1]; /* directional status stack */
struct bidi_string_data string; /* string to reorder */
struct window *w; /* the window being displayed */
bidi_dir_t paragraph_dir; /* current paragraph direction */