1
Fork 0
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:
Eli Zaretskii 2011-05-21 17:22:14 +03:00
parent 683a44f77c
commit fc6f18ceea
4 changed files with 302 additions and 182 deletions

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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;