mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-30 20:32:00 -08:00
Discovery of replacing display properties now uses the same code
as the display engine. Tested OK with display properties whose value is a list. src/dispextern.h (struct bidi_it): New member frame_window_p. (bidi_init_it, compute_display_string_pos): Update prototypes. src/bidi.c (bidi_fetch_char): Accept additional argument FRAME_WINDOW_P and pass it to compute_display_string_pos. All callers changed. (bidi_init_it): Accept additional argument FRAME_WINDOW_P and use it to initialize the frame_window_p member of struct bidi_it. src/xdisp.c (handle_display_spec): New function, refactored from the last portion of handle_display_prop. (compute_display_string_pos): Accept additional argument FRAME_WINDOW_P. Call handle_display_spec to determine whether the value of a `display' property is a "replacing spec". (handle_single_display_spec): Accept 2 additional arguments BUFPOS and FRAME_WINDOW_P. If IT is NULL, don't set up the iterator from the display property, but just return a value indicating whether the display property will replace the characters it covers. (Fcurrent_bidi_paragraph_direction): Initialize the nchars and frame_window_p members of struct bidi_it.
This commit is contained in:
parent
683a44f77c
commit
fc6f18ceea
4 changed files with 302 additions and 182 deletions
|
|
@ -1,3 +1,26 @@
|
|||
2011-05-21 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* xdisp.c (handle_display_spec): New function, refactored from the
|
||||
last portion of handle_display_prop.
|
||||
(compute_display_string_pos): Accept additional argument
|
||||
FRAME_WINDOW_P. Call handle_display_spec to determine whether the
|
||||
value of a `display' property is a "replacing spec".
|
||||
(handle_single_display_spec): Accept 2 additional arguments BUFPOS
|
||||
and FRAME_WINDOW_P. If IT is NULL, don't set up the iterator from
|
||||
the display property, but just return a value indicating whether
|
||||
the display property will replace the characters it covers.
|
||||
(Fcurrent_bidi_paragraph_direction): Initialize the nchars and
|
||||
frame_window_p members of struct bidi_it.
|
||||
|
||||
* bidi.c (bidi_fetch_char): Accept additional argument
|
||||
FRAME_WINDOW_P and pass it to compute_display_string_pos. All
|
||||
callers changed.
|
||||
(bidi_init_it): Accept additional argument FRAME_WINDOW_P and use
|
||||
it to initialize the frame_window_p member of struct bidi_it.
|
||||
|
||||
* dispextern.h (struct bidi_it): New member frame_window_p.
|
||||
(bidi_init_it, compute_display_string_pos): Update prototypes.
|
||||
|
||||
2011-05-14 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* xdisp.c (compute_display_string_pos): Non-trivial implementation.
|
||||
|
|
|
|||
22
src/bidi.c
22
src/bidi.c
|
|
@ -581,7 +581,7 @@ bidi_line_init (struct bidi_it *bidi_it)
|
|||
string. */
|
||||
static INLINE int
|
||||
bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
|
||||
EMACS_INT *ch_len, EMACS_INT *nchars)
|
||||
int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars)
|
||||
{
|
||||
int ch;
|
||||
|
||||
|
|
@ -589,7 +589,7 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
|
|||
/* If we got past the last known position of display string, compute
|
||||
the position of the next one. That position could be at BYTEPOS. */
|
||||
if (charpos < ZV && charpos > *disp_pos)
|
||||
*disp_pos = compute_display_string_pos (charpos);
|
||||
*disp_pos = compute_display_string_pos (charpos, frame_window_p);
|
||||
|
||||
/* Fetch the character at BYTEPOS. */
|
||||
if (bytepos >= ZV_BYTE)
|
||||
|
|
@ -625,7 +625,7 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
|
|||
/* If we just entered a run of characters covered by a display
|
||||
string, compute the position of the next display string. */
|
||||
if (charpos + *nchars <= ZV && charpos + *nchars > *disp_pos)
|
||||
*disp_pos = compute_display_string_pos (charpos + *nchars);
|
||||
*disp_pos = compute_display_string_pos (charpos + *nchars, frame_window_p);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
|
@ -754,7 +754,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
|
|||
do {
|
||||
bytepos = pstartbyte;
|
||||
pos = BYTE_TO_CHAR (bytepos);
|
||||
ch = bidi_fetch_char (bytepos, pos, &disp_pos, &ch_len, &nchars);
|
||||
ch = bidi_fetch_char (bytepos, pos, &disp_pos, bidi_it->frame_window_p,
|
||||
&ch_len, &nchars);
|
||||
type = bidi_get_type (ch, NEUTRAL_DIR);
|
||||
|
||||
for (pos += nchars, bytepos += ch_len;
|
||||
|
|
@ -778,7 +779,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
|
|||
break;
|
||||
}
|
||||
/* Fetch next character and advance to get past it. */
|
||||
ch = bidi_fetch_char (bytepos, pos, &disp_pos, &ch_len, &nchars);
|
||||
ch = bidi_fetch_char (bytepos, pos, &disp_pos,
|
||||
bidi_it->frame_window_p, &ch_len, &nchars);
|
||||
pos += nchars;
|
||||
bytepos += ch_len;
|
||||
}
|
||||
|
|
@ -840,12 +842,14 @@ bidi_set_paragraph_end (struct bidi_it *bidi_it)
|
|||
|
||||
/* Initialize the bidi iterator from buffer/string position CHARPOS. */
|
||||
void
|
||||
bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, struct bidi_it *bidi_it)
|
||||
bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p,
|
||||
struct bidi_it *bidi_it)
|
||||
{
|
||||
if (! bidi_initialized)
|
||||
bidi_initialize ();
|
||||
bidi_it->charpos = charpos;
|
||||
bidi_it->bytepos = bytepos;
|
||||
bidi_it->frame_window_p = frame_window_p;
|
||||
bidi_it->nchars = -1; /* to be computed in bidi_resolve_explicit_1 */
|
||||
bidi_it->first_elt = 1;
|
||||
bidi_set_paragraph_end (bidi_it);
|
||||
|
|
@ -996,7 +1000,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
|
|||
display string, treat the entire run of covered characters as
|
||||
a single character u+FFFC. */
|
||||
curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos,
|
||||
&bidi_it->disp_pos,
|
||||
&bidi_it->disp_pos, bidi_it->frame_window_p,
|
||||
&bidi_it->ch_len, &bidi_it->nchars);
|
||||
}
|
||||
bidi_it->ch = curchar;
|
||||
|
|
@ -1674,11 +1678,13 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
|
|||
EMACS_INT disp_pos = bidi_it->disp_pos;
|
||||
EMACS_INT nc = bidi_it->nchars;
|
||||
bidi_type_t chtype;
|
||||
int fwp = bidi_it->frame_window_p;
|
||||
|
||||
if (bidi_it->nchars <= 0)
|
||||
abort ();
|
||||
do {
|
||||
ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &clen, &nc);
|
||||
ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, fwp,
|
||||
&clen, &nc);
|
||||
if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */)
|
||||
chtype = NEUTRAL_B;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1847,6 +1847,7 @@ struct bidi_it {
|
|||
int first_elt; /* if non-zero, examine current char first */
|
||||
bidi_dir_t paragraph_dir; /* current paragraph direction */
|
||||
int new_paragraph; /* if non-zero, we expect a new paragraph */
|
||||
int frame_window_p; /* non-zero if displaying on a GUI frame */
|
||||
EMACS_INT separator_limit; /* where paragraph separator should end */
|
||||
EMACS_INT disp_pos; /* position of display string after ch */
|
||||
};
|
||||
|
|
@ -2945,7 +2946,7 @@ enum tool_bar_item_image
|
|||
|
||||
/* Defined in bidi.c */
|
||||
|
||||
extern void bidi_init_it (EMACS_INT, EMACS_INT, struct bidi_it *);
|
||||
extern void bidi_init_it (EMACS_INT, EMACS_INT, int, struct bidi_it *);
|
||||
extern void bidi_move_to_visually_next (struct bidi_it *);
|
||||
extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int);
|
||||
extern int bidi_mirror_char (int);
|
||||
|
|
@ -3006,7 +3007,7 @@ extern void reseat_at_previous_visible_line_start (struct it *);
|
|||
extern Lisp_Object lookup_glyphless_char_display (int, struct it *);
|
||||
extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object,
|
||||
struct font *, int, int *);
|
||||
extern EMACS_INT compute_display_string_pos (EMACS_INT);
|
||||
extern EMACS_INT compute_display_string_pos (EMACS_INT, int);
|
||||
extern EMACS_INT compute_display_string_end (EMACS_INT);
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
|
|
|
|||
434
src/xdisp.c
434
src/xdisp.c
|
|
@ -884,9 +884,11 @@ static void compute_string_pos (struct text_pos *, struct text_pos,
|
|||
Lisp_Object);
|
||||
static int face_before_or_after_it_pos (struct it *, int);
|
||||
static EMACS_INT next_overlay_change (EMACS_INT);
|
||||
static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
|
||||
Lisp_Object, struct text_pos *, EMACS_INT, int);
|
||||
static int handle_single_display_spec (struct it *, Lisp_Object,
|
||||
Lisp_Object, Lisp_Object,
|
||||
struct text_pos *, int);
|
||||
struct text_pos *, EMACS_INT, int, int);
|
||||
static int underlying_face_id (struct it *);
|
||||
static int in_ellipses_for_invisible_text_p (struct display_pos *,
|
||||
struct window *);
|
||||
|
|
@ -2564,7 +2566,7 @@ init_iterator (struct it *it, struct window *w,
|
|||
it->paragraph_embedding = R2L;
|
||||
else
|
||||
it->paragraph_embedding = NEUTRAL_DIR;
|
||||
bidi_init_it (charpos, bytepos, &it->bidi_it);
|
||||
bidi_init_it (charpos, bytepos, FRAME_WINDOW_P (it->f), &it->bidi_it);
|
||||
}
|
||||
|
||||
/* If a buffer position was specified, set the iterator there,
|
||||
|
|
@ -3086,37 +3088,54 @@ next_overlay_change (EMACS_INT pos)
|
|||
}
|
||||
|
||||
/* Return the character position of a display string at or after CHARPOS.
|
||||
If no display string exist at or after CHARPOS, return ZV. A
|
||||
If no display string exists at or after CHARPOS, return ZV. A
|
||||
display string is either an overlay with `display' property whose
|
||||
value is a string or a `display' text property whose value is a
|
||||
string. */
|
||||
value is a string, or a `display' text property whose value is a
|
||||
string. FRAME_WINDOW_P is non-zero when we are displaying a window
|
||||
on a GUI frame. */
|
||||
EMACS_INT
|
||||
compute_display_string_pos (EMACS_INT charpos)
|
||||
compute_display_string_pos (EMACS_INT charpos, int frame_window_p)
|
||||
{
|
||||
/* FIXME: Support display properties on strings (object = Qnil means
|
||||
current buffer). */
|
||||
Lisp_Object object = Qnil;
|
||||
Lisp_Object pos = make_number (charpos);
|
||||
Lisp_Object pos, spec;
|
||||
struct text_pos position;
|
||||
EMACS_INT bufpos;
|
||||
|
||||
if (charpos >= ZV)
|
||||
return ZV;
|
||||
|
||||
/* If the character at CHARPOS is where the display string begins,
|
||||
return CHARPOS. */
|
||||
if (!NILP (Fget_char_property (pos, Qdisplay, object))
|
||||
pos = make_number (charpos);
|
||||
CHARPOS (position) = charpos;
|
||||
BYTEPOS (position) = CHAR_TO_BYTE (charpos);
|
||||
bufpos = charpos; /* FIXME! support strings as well */
|
||||
if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
|
||||
&& (charpos <= BEGV
|
||||
|| NILP (Fget_char_property (make_number (charpos - 1), Qdisplay,
|
||||
object))))
|
||||
|| !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
|
||||
object),
|
||||
spec)))
|
||||
&& handle_display_spec (NULL, spec, object, Qnil, &position, bufpos,
|
||||
frame_window_p))
|
||||
return charpos;
|
||||
|
||||
/* Look forward for the first character where the `display' property
|
||||
changes from nil to non-nil. */
|
||||
/* Look forward for the first character with a `display' property
|
||||
that will replace the underlying text when displayed. */
|
||||
do {
|
||||
pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
|
||||
} while (XFASTINT (pos) < ZV
|
||||
&& NILP (Fget_char_property (pos, Qdisplay, object)));
|
||||
CHARPOS (position) = XFASTINT (pos);
|
||||
BYTEPOS (position) = CHAR_TO_BYTE (CHARPOS (position));
|
||||
if (CHARPOS (position) >= ZV)
|
||||
break;
|
||||
spec = Fget_char_property (pos, Qdisplay, object);
|
||||
bufpos = CHARPOS (position); /* FIXME! support strings as well */
|
||||
} while (NILP (spec)
|
||||
|| !handle_display_spec (NULL, spec, object, Qnil, &position, bufpos,
|
||||
frame_window_p));
|
||||
|
||||
return XFASTINT (pos);
|
||||
return CHARPOS (position);
|
||||
}
|
||||
|
||||
/* Return the character position of the end of the display string that
|
||||
|
|
@ -3802,8 +3821,9 @@ setup_for_ellipsis (struct it *it, int len)
|
|||
static enum prop_handled
|
||||
handle_display_prop (struct it *it)
|
||||
{
|
||||
Lisp_Object prop, object, overlay;
|
||||
Lisp_Object propval, object, overlay;
|
||||
struct text_pos *position;
|
||||
EMACS_INT bufpos;
|
||||
/* Nonzero if some property replaces the display of the text itself. */
|
||||
int display_replaced_p = 0;
|
||||
|
||||
|
|
@ -3811,11 +3831,13 @@ handle_display_prop (struct it *it)
|
|||
{
|
||||
object = it->string;
|
||||
position = &it->current.string_pos;
|
||||
bufpos = CHARPOS (it->current.pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
XSETWINDOW (object, it->w);
|
||||
position = &it->current.pos;
|
||||
bufpos = CHARPOS (*position);
|
||||
}
|
||||
|
||||
/* Reset those iterator values set from display property values. */
|
||||
|
|
@ -3830,9 +3852,9 @@ handle_display_prop (struct it *it)
|
|||
if (!it->string_from_display_prop_p)
|
||||
it->area = TEXT_AREA;
|
||||
|
||||
prop = get_char_property_and_overlay (make_number (position->charpos),
|
||||
Qdisplay, object, &overlay);
|
||||
if (NILP (prop))
|
||||
propval = get_char_property_and_overlay (make_number (position->charpos),
|
||||
Qdisplay, object, &overlay);
|
||||
if (NILP (propval))
|
||||
return HANDLED_NORMALLY;
|
||||
/* Now OVERLAY is the overlay that gave us this property, or nil
|
||||
if it was a text property. */
|
||||
|
|
@ -3840,59 +3862,88 @@ handle_display_prop (struct it *it)
|
|||
if (!STRINGP (it->string))
|
||||
object = it->w->buffer;
|
||||
|
||||
if (CONSP (prop)
|
||||
/* Simple properties. */
|
||||
&& !EQ (XCAR (prop), Qimage)
|
||||
&& !EQ (XCAR (prop), Qspace)
|
||||
&& !EQ (XCAR (prop), Qwhen)
|
||||
&& !EQ (XCAR (prop), Qslice)
|
||||
&& !EQ (XCAR (prop), Qspace_width)
|
||||
&& !EQ (XCAR (prop), Qheight)
|
||||
&& !EQ (XCAR (prop), Qraise)
|
||||
display_replaced_p = handle_display_spec (it, propval, object, overlay,
|
||||
position, bufpos,
|
||||
FRAME_WINDOW_P (it->f));
|
||||
|
||||
return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
|
||||
}
|
||||
|
||||
/* Subroutine of handle_display_prop. Returns non-zero if the display
|
||||
specification in SPEC is a replacing specification, i.e. it would
|
||||
replace the text covered by `display' property with something else,
|
||||
such as an image or a display string.
|
||||
|
||||
See handle_single_display_spec for documentation of arguments.
|
||||
frame_window_p is non-zero if the window being redisplayed is on a
|
||||
GUI frame; this argument is used only if IT is NULL, see below.
|
||||
|
||||
IT can be NULL, if this is called by the bidi reordering code
|
||||
through compute_display_string_pos, which see. In that case, this
|
||||
function only examines SPEC, but does not otherwise "handle" it, in
|
||||
the sense that it doesn't set up members of IT from the display
|
||||
spec. */
|
||||
static int
|
||||
handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
||||
Lisp_Object overlay, struct text_pos *position,
|
||||
EMACS_INT bufpos, int frame_window_p)
|
||||
{
|
||||
int replacing_p = 0;
|
||||
|
||||
if (CONSP (spec)
|
||||
/* Simple specerties. */
|
||||
&& !EQ (XCAR (spec), Qimage)
|
||||
&& !EQ (XCAR (spec), Qspace)
|
||||
&& !EQ (XCAR (spec), Qwhen)
|
||||
&& !EQ (XCAR (spec), Qslice)
|
||||
&& !EQ (XCAR (spec), Qspace_width)
|
||||
&& !EQ (XCAR (spec), Qheight)
|
||||
&& !EQ (XCAR (spec), Qraise)
|
||||
/* Marginal area specifications. */
|
||||
&& !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
|
||||
&& !EQ (XCAR (prop), Qleft_fringe)
|
||||
&& !EQ (XCAR (prop), Qright_fringe)
|
||||
&& !NILP (XCAR (prop)))
|
||||
&& !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
|
||||
&& !EQ (XCAR (spec), Qleft_fringe)
|
||||
&& !EQ (XCAR (spec), Qright_fringe)
|
||||
&& !NILP (XCAR (spec)))
|
||||
{
|
||||
for (; CONSP (prop); prop = XCDR (prop))
|
||||
for (; CONSP (spec); spec = XCDR (spec))
|
||||
{
|
||||
if (handle_single_display_spec (it, XCAR (prop), object, overlay,
|
||||
position, display_replaced_p))
|
||||
if (handle_single_display_spec (it, XCAR (spec), object, overlay,
|
||||
position, bufpos, replacing_p,
|
||||
frame_window_p))
|
||||
{
|
||||
display_replaced_p = 1;
|
||||
replacing_p = 1;
|
||||
/* If some text in a string is replaced, `position' no
|
||||
longer points to the position of `object'. */
|
||||
if (STRINGP (object))
|
||||
if (!it || STRINGP (object))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (VECTORP (prop))
|
||||
else if (VECTORP (spec))
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ASIZE (prop); ++i)
|
||||
if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
|
||||
position, display_replaced_p))
|
||||
for (i = 0; i < ASIZE (spec); ++i)
|
||||
if (handle_single_display_spec (it, AREF (spec, i), object, overlay,
|
||||
position, bufpos, replacing_p,
|
||||
frame_window_p))
|
||||
{
|
||||
display_replaced_p = 1;
|
||||
replacing_p = 1;
|
||||
/* If some text in a string is replaced, `position' no
|
||||
longer points to the position of `object'. */
|
||||
if (STRINGP (object))
|
||||
if (!it || STRINGP (object))
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (handle_single_display_spec (it, prop, object, overlay,
|
||||
position, 0))
|
||||
display_replaced_p = 1;
|
||||
if (handle_single_display_spec (it, spec, object, overlay,
|
||||
position, bufpos, 0, frame_window_p))
|
||||
replacing_p = 1;
|
||||
}
|
||||
|
||||
return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
|
||||
return replacing_p;
|
||||
}
|
||||
|
||||
|
||||
/* Value is the position of the end of the `display' property starting
|
||||
at START_POS in OBJECT. */
|
||||
|
||||
|
|
@ -3916,10 +3967,12 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
|
|||
|
||||
/* Set up IT from a single `display' property specification SPEC. OBJECT
|
||||
is the object in which the `display' property was found. *POSITION
|
||||
is the position at which it was found. DISPLAY_REPLACED_P non-zero
|
||||
means that we previously saw a display specification which already
|
||||
replaced text display with something else, for example an image;
|
||||
we ignore such properties after the first one has been processed.
|
||||
is the position in OBJECT at which the `display' property was found.
|
||||
BUFPOS is the buffer position of OBJECT (different from POSITION if
|
||||
OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
|
||||
previously saw a display specification which already replaced text
|
||||
display with something else, for example an image; we ignore such
|
||||
properties after the first one has been processed.
|
||||
|
||||
OVERLAY is the overlay this `display' property came from,
|
||||
or nil if it was a text property.
|
||||
|
|
@ -3928,17 +3981,22 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
|
|||
cases too, set *POSITION to the position where the `display'
|
||||
property ends.
|
||||
|
||||
If IT is NULL, only examine the property specification in SPEC, but
|
||||
don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
|
||||
is intended to be displayed in a window on a GUI frame.
|
||||
|
||||
Value is non-zero if something was found which replaces the display
|
||||
of buffer or string text. */
|
||||
|
||||
static int
|
||||
handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
||||
Lisp_Object overlay, struct text_pos *position,
|
||||
int display_replaced_p)
|
||||
EMACS_INT bufpos, int display_replaced_p,
|
||||
int frame_window_p)
|
||||
{
|
||||
Lisp_Object form;
|
||||
Lisp_Object location, value;
|
||||
struct text_pos start_pos;
|
||||
struct text_pos start_pos = *position;
|
||||
int valid_p;
|
||||
|
||||
/* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
|
||||
|
|
@ -3962,11 +4020,12 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
|||
buffer or string. Bind `position' to the position in the
|
||||
object where the property was found, and `buffer-position'
|
||||
to the current position in the buffer. */
|
||||
|
||||
if (NILP (object))
|
||||
XSETBUFFER (object, current_buffer);
|
||||
specbind (Qobject, object);
|
||||
specbind (Qposition, make_number (CHARPOS (*position)));
|
||||
specbind (Qbuffer_position,
|
||||
make_number (STRINGP (object)
|
||||
? IT_CHARPOS (*it) : CHARPOS (*position)));
|
||||
specbind (Qbuffer_position, make_number (bufpos));
|
||||
GCPRO1 (form);
|
||||
form = safe_eval (form);
|
||||
UNGCPRO;
|
||||
|
|
@ -3981,63 +4040,66 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
|||
&& EQ (XCAR (spec), Qheight)
|
||||
&& CONSP (XCDR (spec)))
|
||||
{
|
||||
if (!FRAME_WINDOW_P (it->f))
|
||||
return 0;
|
||||
|
||||
it->font_height = XCAR (XCDR (spec));
|
||||
if (!NILP (it->font_height))
|
||||
if (it)
|
||||
{
|
||||
struct face *face = FACE_FROM_ID (it->f, it->face_id);
|
||||
int new_height = -1;
|
||||
if (!FRAME_WINDOW_P (it->f))
|
||||
return 0;
|
||||
|
||||
if (CONSP (it->font_height)
|
||||
&& (EQ (XCAR (it->font_height), Qplus)
|
||||
|| EQ (XCAR (it->font_height), Qminus))
|
||||
&& CONSP (XCDR (it->font_height))
|
||||
&& INTEGERP (XCAR (XCDR (it->font_height))))
|
||||
it->font_height = XCAR (XCDR (spec));
|
||||
if (!NILP (it->font_height))
|
||||
{
|
||||
/* `(+ N)' or `(- N)' where N is an integer. */
|
||||
int steps = XINT (XCAR (XCDR (it->font_height)));
|
||||
if (EQ (XCAR (it->font_height), Qplus))
|
||||
steps = - steps;
|
||||
it->face_id = smaller_face (it->f, it->face_id, steps);
|
||||
}
|
||||
else if (FUNCTIONP (it->font_height))
|
||||
{
|
||||
/* Call function with current height as argument.
|
||||
Value is the new height. */
|
||||
Lisp_Object height;
|
||||
height = safe_call1 (it->font_height,
|
||||
face->lface[LFACE_HEIGHT_INDEX]);
|
||||
if (NUMBERP (height))
|
||||
new_height = XFLOATINT (height);
|
||||
}
|
||||
else if (NUMBERP (it->font_height))
|
||||
{
|
||||
/* Value is a multiple of the canonical char height. */
|
||||
struct face *f;
|
||||
struct face *face = FACE_FROM_ID (it->f, it->face_id);
|
||||
int new_height = -1;
|
||||
|
||||
f = FACE_FROM_ID (it->f,
|
||||
lookup_basic_face (it->f, DEFAULT_FACE_ID));
|
||||
new_height = (XFLOATINT (it->font_height)
|
||||
* XINT (f->lface[LFACE_HEIGHT_INDEX]));
|
||||
if (CONSP (it->font_height)
|
||||
&& (EQ (XCAR (it->font_height), Qplus)
|
||||
|| EQ (XCAR (it->font_height), Qminus))
|
||||
&& CONSP (XCDR (it->font_height))
|
||||
&& INTEGERP (XCAR (XCDR (it->font_height))))
|
||||
{
|
||||
/* `(+ N)' or `(- N)' where N is an integer. */
|
||||
int steps = XINT (XCAR (XCDR (it->font_height)));
|
||||
if (EQ (XCAR (it->font_height), Qplus))
|
||||
steps = - steps;
|
||||
it->face_id = smaller_face (it->f, it->face_id, steps);
|
||||
}
|
||||
else if (FUNCTIONP (it->font_height))
|
||||
{
|
||||
/* Call function with current height as argument.
|
||||
Value is the new height. */
|
||||
Lisp_Object height;
|
||||
height = safe_call1 (it->font_height,
|
||||
face->lface[LFACE_HEIGHT_INDEX]);
|
||||
if (NUMBERP (height))
|
||||
new_height = XFLOATINT (height);
|
||||
}
|
||||
else if (NUMBERP (it->font_height))
|
||||
{
|
||||
/* Value is a multiple of the canonical char height. */
|
||||
struct face *f;
|
||||
|
||||
f = FACE_FROM_ID (it->f,
|
||||
lookup_basic_face (it->f, DEFAULT_FACE_ID));
|
||||
new_height = (XFLOATINT (it->font_height)
|
||||
* XINT (f->lface[LFACE_HEIGHT_INDEX]));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Evaluate IT->font_height with `height' bound to the
|
||||
current specified height to get the new height. */
|
||||
int count = SPECPDL_INDEX ();
|
||||
|
||||
specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
|
||||
value = safe_eval (it->font_height);
|
||||
unbind_to (count, Qnil);
|
||||
|
||||
if (NUMBERP (value))
|
||||
new_height = XFLOATINT (value);
|
||||
}
|
||||
|
||||
if (new_height > 0)
|
||||
it->face_id = face_with_height (it->f, it->face_id, new_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Evaluate IT->font_height with `height' bound to the
|
||||
current specified height to get the new height. */
|
||||
int count = SPECPDL_INDEX ();
|
||||
|
||||
specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
|
||||
value = safe_eval (it->font_height);
|
||||
unbind_to (count, Qnil);
|
||||
|
||||
if (NUMBERP (value))
|
||||
new_height = XFLOATINT (value);
|
||||
}
|
||||
|
||||
if (new_height > 0)
|
||||
it->face_id = face_with_height (it->f, it->face_id, new_height);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -4048,12 +4110,15 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
|||
&& EQ (XCAR (spec), Qspace_width)
|
||||
&& CONSP (XCDR (spec)))
|
||||
{
|
||||
if (!FRAME_WINDOW_P (it->f))
|
||||
return 0;
|
||||
if (it)
|
||||
{
|
||||
if (!FRAME_WINDOW_P (it->f))
|
||||
return 0;
|
||||
|
||||
value = XCAR (XCDR (spec));
|
||||
if (NUMBERP (value) && XFLOATINT (value) > 0)
|
||||
it->space_width = value;
|
||||
value = XCAR (XCDR (spec));
|
||||
if (NUMBERP (value) && XFLOATINT (value) > 0)
|
||||
it->space_width = value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4064,20 +4129,23 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
|||
{
|
||||
Lisp_Object tem;
|
||||
|
||||
if (!FRAME_WINDOW_P (it->f))
|
||||
return 0;
|
||||
|
||||
if (tem = XCDR (spec), CONSP (tem))
|
||||
if (it)
|
||||
{
|
||||
it->slice.x = XCAR (tem);
|
||||
if (tem = XCDR (tem), CONSP (tem))
|
||||
if (!FRAME_WINDOW_P (it->f))
|
||||
return 0;
|
||||
|
||||
if (tem = XCDR (spec), CONSP (tem))
|
||||
{
|
||||
it->slice.y = XCAR (tem);
|
||||
it->slice.x = XCAR (tem);
|
||||
if (tem = XCDR (tem), CONSP (tem))
|
||||
{
|
||||
it->slice.width = XCAR (tem);
|
||||
it->slice.y = XCAR (tem);
|
||||
if (tem = XCDR (tem), CONSP (tem))
|
||||
it->slice.height = XCAR (tem);
|
||||
{
|
||||
it->slice.width = XCAR (tem);
|
||||
if (tem = XCDR (tem), CONSP (tem))
|
||||
it->slice.height = XCAR (tem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4090,36 +4158,43 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
|||
&& EQ (XCAR (spec), Qraise)
|
||||
&& CONSP (XCDR (spec)))
|
||||
{
|
||||
if (!FRAME_WINDOW_P (it->f))
|
||||
return 0;
|
||||
if (it)
|
||||
{
|
||||
if (!FRAME_WINDOW_P (it->f))
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
value = XCAR (XCDR (spec));
|
||||
if (NUMBERP (value))
|
||||
{
|
||||
struct face *face = FACE_FROM_ID (it->f, it->face_id);
|
||||
it->voffset = - (XFLOATINT (value)
|
||||
* (FONT_HEIGHT (face->font)));
|
||||
}
|
||||
value = XCAR (XCDR (spec));
|
||||
if (NUMBERP (value))
|
||||
{
|
||||
struct face *face = FACE_FROM_ID (it->f, it->face_id);
|
||||
it->voffset = - (XFLOATINT (value)
|
||||
* (FONT_HEIGHT (face->font)));
|
||||
}
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Don't handle the other kinds of display specifications
|
||||
inside a string that we got from a `display' property. */
|
||||
if (it->string_from_display_prop_p)
|
||||
if (it && it->string_from_display_prop_p)
|
||||
return 0;
|
||||
|
||||
/* Characters having this form of property are not displayed, so
|
||||
we have to find the end of the property. */
|
||||
start_pos = *position;
|
||||
*position = display_prop_end (it, object, start_pos);
|
||||
if (it)
|
||||
{
|
||||
start_pos = *position;
|
||||
*position = display_prop_end (it, object, start_pos);
|
||||
}
|
||||
value = Qnil;
|
||||
|
||||
/* Stop the scan at that end position--we assume that all
|
||||
text properties change there. */
|
||||
it->stop_charpos = position->charpos;
|
||||
if (it)
|
||||
it->stop_charpos = position->charpos;
|
||||
|
||||
/* Handle `(left-fringe BITMAP [FACE])'
|
||||
and `(right-fringe BITMAP [FACE])'. */
|
||||
|
|
@ -4128,12 +4203,16 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
|||
|| EQ (XCAR (spec), Qright_fringe))
|
||||
&& CONSP (XCDR (spec)))
|
||||
{
|
||||
int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
|
||||
int fringe_bitmap;
|
||||
|
||||
if (!FRAME_WINDOW_P (it->f))
|
||||
/* If we return here, POSITION has been advanced
|
||||
across the text with this property. */
|
||||
if (it)
|
||||
{
|
||||
if (!FRAME_WINDOW_P (it->f))
|
||||
/* If we return here, POSITION has been advanced
|
||||
across the text with this property. */
|
||||
return 0;
|
||||
}
|
||||
else if (!frame_window_p)
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
|
|
@ -4144,42 +4223,47 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
|||
across the text with this property. */
|
||||
return 0;
|
||||
|
||||
if (CONSP (XCDR (XCDR (spec))))
|
||||
if (it)
|
||||
{
|
||||
Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
|
||||
int face_id2 = lookup_derived_face (it->f, face_name,
|
||||
FRINGE_FACE_ID, 0);
|
||||
if (face_id2 >= 0)
|
||||
face_id = face_id2;
|
||||
}
|
||||
int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
|
||||
|
||||
/* Save current settings of IT so that we can restore them
|
||||
when we are finished with the glyph property value. */
|
||||
push_it (it, position);
|
||||
if (CONSP (XCDR (XCDR (spec))))
|
||||
{
|
||||
Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
|
||||
int face_id2 = lookup_derived_face (it->f, face_name,
|
||||
FRINGE_FACE_ID, 0);
|
||||
if (face_id2 >= 0)
|
||||
face_id = face_id2;
|
||||
}
|
||||
|
||||
it->area = TEXT_AREA;
|
||||
it->what = IT_IMAGE;
|
||||
it->image_id = -1; /* no image */
|
||||
it->position = start_pos;
|
||||
it->object = NILP (object) ? it->w->buffer : object;
|
||||
it->method = GET_FROM_IMAGE;
|
||||
it->from_overlay = Qnil;
|
||||
it->face_id = face_id;
|
||||
/* Save current settings of IT so that we can restore them
|
||||
when we are finished with the glyph property value. */
|
||||
push_it (it, position);
|
||||
|
||||
/* Say that we haven't consumed the characters with
|
||||
`display' property yet. The call to pop_it in
|
||||
set_iterator_to_next will clean this up. */
|
||||
*position = start_pos;
|
||||
it->area = TEXT_AREA;
|
||||
it->what = IT_IMAGE;
|
||||
it->image_id = -1; /* no image */
|
||||
it->position = start_pos;
|
||||
it->object = NILP (object) ? it->w->buffer : object;
|
||||
it->method = GET_FROM_IMAGE;
|
||||
it->from_overlay = Qnil;
|
||||
it->face_id = face_id;
|
||||
|
||||
if (EQ (XCAR (spec), Qleft_fringe))
|
||||
{
|
||||
it->left_user_fringe_bitmap = fringe_bitmap;
|
||||
it->left_user_fringe_face_id = face_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
it->right_user_fringe_bitmap = fringe_bitmap;
|
||||
it->right_user_fringe_face_id = face_id;
|
||||
/* Say that we haven't consumed the characters with
|
||||
`display' property yet. The call to pop_it in
|
||||
set_iterator_to_next will clean this up. */
|
||||
*position = start_pos;
|
||||
|
||||
if (EQ (XCAR (spec), Qleft_fringe))
|
||||
{
|
||||
it->left_user_fringe_bitmap = fringe_bitmap;
|
||||
it->left_user_fringe_face_id = face_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
it->right_user_fringe_bitmap = fringe_bitmap;
|
||||
it->right_user_fringe_face_id = face_id;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
return 1;
|
||||
|
|
@ -4222,12 +4306,16 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
|||
|
||||
valid_p = (STRINGP (value)
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
|| (FRAME_WINDOW_P (it->f) && valid_image_p (value))
|
||||
|| ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
|
||||
&& valid_image_p (value))
|
||||
#endif /* not HAVE_WINDOW_SYSTEM */
|
||||
|| (CONSP (value) && EQ (XCAR (value), Qspace)));
|
||||
|
||||
if (valid_p && !display_replaced_p)
|
||||
{
|
||||
if (!it)
|
||||
return 1;
|
||||
|
||||
/* Save current settings of IT so that we can restore them
|
||||
when we are finished with the glyph property value. */
|
||||
push_it (it, position);
|
||||
|
|
@ -18080,6 +18168,8 @@ See also `bidi-paragraph-direction'. */)
|
|||
bytepos--;
|
||||
itb.charpos = pos;
|
||||
itb.bytepos = bytepos;
|
||||
itb.nchars = -1;
|
||||
itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */
|
||||
itb.first_elt = 1;
|
||||
itb.separator_limit = -1;
|
||||
itb.paragraph_dir = NEUTRAL_DIR;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue