From: Eli Zaretskii Date: Sat, 21 May 2011 14:22:14 +0000 (+0300) Subject: Discovery of replacing display properties now uses the same code X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~39 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=fc6f18ceeaae3c3eb4d68120899e16c2fc73ea86;p=emacs.git 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. --- 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 + + * 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 * 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)) + it->font_height = XCAR (XCDR (spec)); + if (!NILP (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; + + 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 (); + 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); + 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 (NUMBERP (value)) + new_height = XFLOATINT (value); + } - if (new_height > 0) - it->face_id = face_with_height (it->f, it->face_id, new_height); + 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;