summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2011-05-21 17:22:14 +0300
committerEli Zaretskii <eliz@gnu.org>2011-05-21 17:22:14 +0300
commitfc6f18ceeaae3c3eb4d68120899e16c2fc73ea86 (patch)
treedbbc17ffa38f01c0fe0184605569c1051f6eec8d /src
parent683a44f77c8c83febe1ab7ebe7fc32d26fc71bcd (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog23
-rw-r--r--src/bidi.c22
-rw-r--r--src/dispextern.h5
-rw-r--r--src/xdisp.c430
4 files changed, 300 insertions, 180 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index fdb98351672..f7807b90941 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -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.
diff --git a/src/bidi.c b/src/bidi.c
index 742224607e4..17cb1214c73 100644
--- a/src/bidi.c
+++ b/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
diff --git a/src/dispextern.h b/src/dispextern.h
index f5036169f75..6c09f21a78f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -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
diff --git a/src/xdisp.c b/src/xdisp.c
index 6ea6f92a3f7..8665acf8fdd 100644
--- a/src/xdisp.c
+++ b/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))))
- {
- /* `(+ 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))
+ it->font_height = XCAR (XCDR (spec));
+ if (!NILP (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]));
- }
- else
- {
- /* Evaluate IT->font_height with `height' bound to the
- current specified height to get the new height. */
- int count = SPECPDL_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;
- specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
- value = safe_eval (it->font_height);
- unbind_to (count, Qnil);
+ 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 ();
- if (NUMBERP (value))
- new_height = XFLOATINT (value);
- }
+ specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
+ value = safe_eval (it->font_height);
+ unbind_to (count, Qnil);
- if (new_height > 0)
- it->face_id = face_with_height (it->f, it->face_id, new_height);
+ 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;