still left to right, i.e. the iterator "thinks" the first character
is at the leftmost pixel position. The iterator does not know that
PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
- delivers. This is important when functions from the the move_it_*
+ delivers. This is important when functions from the move_it_*
family are used to get to certain screen position or to match
screen coordinates with buffer coordinates: these functions use the
iterator geometry, which is left to right even in R2L paragraphs.
static int store_mode_line_noprop (const char *, int, int);
static void handle_stop (struct it *);
static void handle_stop_backwards (struct it *, EMACS_INT);
-static int single_display_spec_intangible_p (Lisp_Object);
static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
static void ensure_echo_area_buffers (void);
static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
static int trailing_whitespace_p (EMACS_INT);
static unsigned long int message_log_check_duplicate (EMACS_INT, EMACS_INT);
-static void push_it (struct it *);
+static void push_it (struct it *, struct text_pos *);
static void pop_it (struct it *);
static void sync_frame_with_window_matrix_rows (struct window *);
static void select_frame_for_redisplay (Lisp_Object);
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 *);
This is the height of W minus the height of a mode line, if any. */
-INLINE int
+inline int
window_text_bottom_y (struct window *w)
{
int height = WINDOW_TOTAL_HEIGHT (w);
means return the total width of W, not including fringes to
the left and right of the window. */
-INLINE int
+inline int
window_box_width (struct window *w, int area)
{
int cols = XFASTINT (w->total_cols);
/* Return the pixel height of the display area of window W, not
including mode lines of W, if any. */
-INLINE int
+inline int
window_box_height (struct window *w)
{
struct frame *f = XFRAME (w->frame);
area AREA of window W. AREA < 0 means return the left edge of the
whole window, to the right of the left fringe of W. */
-INLINE int
+inline int
window_box_left_offset (struct window *w, int area)
{
int x;
area AREA of window W. AREA < 0 means return the right edge of the
whole window, to the left of the right fringe of W. */
-INLINE int
+inline int
window_box_right_offset (struct window *w, int area)
{
return window_box_left_offset (w, area) + window_box_width (w, area);
area AREA of window W. AREA < 0 means return the left edge of the
whole window, to the right of the left fringe of W. */
-INLINE int
+inline int
window_box_left (struct window *w, int area)
{
struct frame *f = XFRAME (w->frame);
area AREA of window W. AREA < 0 means return the right edge of the
whole window, to the left of the right fringe of W. */
-INLINE int
+inline int
window_box_right (struct window *w, int area)
{
return window_box_left (w, area) + window_box_width (w, area);
coordinates of the upper-left corner of the box. Return in
*BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
-INLINE void
+inline void
window_box (struct window *w, int area, int *box_x, int *box_y,
int *box_width, int *box_height)
{
*BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
box. */
-static INLINE void
+static inline void
window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
int *bottom_right_x, int *bottom_right_y)
{
returns an invalid character. If we find one, we return a `?', but
with the length of the invalid character. */
-static INLINE int
+static inline int
string_char_and_length (const unsigned char *str, int *len)
{
int c;
c = STRING_CHAR_AND_LENGTH (str, *len);
- if (!CHAR_VALID_P (c, 1))
+ if (!CHAR_VALID_P (c))
/* We may not change the length here because other places in Emacs
don't use this function, i.e. they silently accept invalid
characters. */
/* Value is the text position, i.e. character and byte position,
for character position CHARPOS in STRING. */
-static INLINE struct text_pos
+static inline struct text_pos
string_pos (EMACS_INT charpos, Lisp_Object string)
{
struct text_pos pos;
redisplay during the evaluation. */
Lisp_Object
-safe_call (size_t nargs, Lisp_Object *args)
+safe_call (ptrdiff_t nargs, Lisp_Object *args)
{
Lisp_Object val;
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,
return endpos;
}
+/* Return the character position of a display string at or after CHARPOS.
+ 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. 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, int frame_window_p)
+{
+ /* FIXME: Support display properties on strings (object = Qnil means
+ current buffer). */
+ Lisp_Object object = Qnil;
+ 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. */
+ 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
+ || !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 with a `display' property
+ that will replace the underlying text when displayed. */
+ do {
+ pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
+ 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 CHARPOS (position);
+}
+
+/* Return the character position of the end of the display string that
+ started at CHARPOS. 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. */
+EMACS_INT
+compute_display_string_end (EMACS_INT charpos)
+{
+ /* FIXME: Support display properties on strings (object = Qnil means
+ current buffer). */
+ Lisp_Object object = Qnil;
+ Lisp_Object pos = make_number (charpos);
+
+ if (charpos >= ZV)
+ return ZV;
+
+ if (NILP (Fget_char_property (pos, Qdisplay, object)))
+ abort ();
+
+ /* Look forward for the first character where the `display' property
+ changes. */
+ pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
+
+ return XFASTINT (pos);
+}
+
\f
/***********************************************************************
_after_ bidi iteration avoids affecting the visual
order of the displayed text when invisible properties
are added or removed. */
- if (it->bidi_it.first_elt)
+ if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
{
/* If we were `reseat'ed to a new paragraph,
determine the paragraph base direction. We need
{
struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
it->dpvec = v->contents;
- it->dpend = v->contents + v->size;
+ it->dpend = v->contents + v->header.size;
}
else
{
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;
{
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. */
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. */
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. */
}
-/* Set up IT from a single `display' specification PROP. OBJECT
+/* 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.
- If PROP is a `space' or `image' specification, and in some other
+ If SPEC is a `space' or `image' specification, and in some other
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_before_p)
+ EMACS_INT bufpos, int display_replaced_p,
+ int frame_window_p)
{
Lisp_Object form;
Lisp_Object location, value;
- struct text_pos start_pos, save_pos;
+ struct text_pos start_pos = *position;
int valid_p;
/* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
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;
&& 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;
&& 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;
}
{
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);
+ }
}
}
}
&& 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])'. */
|| 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
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. */
+ 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;
+ }
- save_pos = it->position;
- it->position = *position;
- push_it (it);
- it->position = save_pos;
+ /* Save current settings of IT so that we can restore them
+ when we are finished with the glyph property value. */
+ push_it (it, position);
- 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;
+ 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;
- /* 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;
+ /* 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;
+ 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;
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_before_p)
+ 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. */
- save_pos = it->position;
- it->position = *position;
- push_it (it);
- it->position = save_pos;
+ push_it (it, position);
it->from_overlay = overlay;
if (NILP (location))
return 0;
}
-
-/* Check if SPEC is a display sub-property value whose text should be
- treated as intangible. */
-
-static int
-single_display_spec_intangible_p (Lisp_Object prop)
-{
- /* Skip over `when FORM'. */
- if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
- {
- prop = XCDR (prop);
- if (!CONSP (prop))
- return 0;
- prop = XCDR (prop);
- }
-
- if (STRINGP (prop))
- return 1;
-
- if (!CONSP (prop))
- return 0;
-
- /* Skip over `margin LOCATION'. If LOCATION is in the margins,
- we don't need to treat text as intangible. */
- if (EQ (XCAR (prop), Qmargin))
- {
- prop = XCDR (prop);
- if (!CONSP (prop))
- return 0;
-
- prop = XCDR (prop);
- if (!CONSP (prop)
- || EQ (XCAR (prop), Qleft_margin)
- || EQ (XCAR (prop), Qright_margin))
- return 0;
- }
-
- return (CONSP (prop)
- && (EQ (XCAR (prop), Qimage)
- || EQ (XCAR (prop), Qspace)));
-}
-
-
/* Check if PROP is a display property value whose text should be
- treated as intangible. */
+ treated as intangible. OVERLAY is the overlay from which PROP
+ came, or nil if it came from a text property. CHARPOS and BYTEPOS
+ specify the buffer position covered by PROP. */
int
-display_prop_intangible_p (Lisp_Object prop)
+display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
+ EMACS_INT charpos, EMACS_INT bytepos)
{
- if (CONSP (prop)
- && CONSP (XCAR (prop))
- && !EQ (Qmargin, XCAR (XCAR (prop))))
- {
- /* A list of sub-properties. */
- while (CONSP (prop))
- {
- if (single_display_spec_intangible_p (XCAR (prop)))
- return 1;
- prop = XCDR (prop);
- }
- }
- else if (VECTORP (prop))
- {
- /* A vector of sub-properties. */
- int i;
- for (i = 0; i < ASIZE (prop); ++i)
- if (single_display_spec_intangible_p (AREF (prop, i)))
- return 1;
- }
- else
- return single_display_spec_intangible_p (prop);
+ int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
+ struct text_pos position;
- return 0;
+ SET_TEXT_POS (position, charpos, bytepos);
+ return handle_display_spec (NULL, prop, Qnil, overlay,
+ &position, charpos, frame_window_p);
}
-/* Return 1 if PROP is a display sub-property value containing STRING. */
+/* Return 1 if PROP is a display sub-property value containing STRING.
+
+ Implementation note: this and the following function are really
+ special cases of handle_display_spec and
+ handle_single_display_spec, and should ideally use the same code.
+ Until they do, these two pairs must be consistent and must be
+ modified in sync. */
static int
single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
prop = XCDR (prop);
if (!CONSP (prop))
return 0;
+ /* Actually, the condition following `when' should be eval'ed,
+ like handle_single_display_spec does, and we should return
+ zero if it evaluates to nil. However, this function is
+ called only when the buffer was already displayed and some
+ glyph in the glyph matrix was found to come from a display
+ string. Therefore, the condition was already evaluated, and
+ the result was non-nil, otherwise the display string wouldn't
+ have been displayed and we would have never been called for
+ this property. Thus, we can skip the evaluation and assume
+ its result is non-nil. */
prop = XCDR (prop);
}
return 0;
}
- return CONSP (prop) && EQ (XCAR (prop), string);
+ return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
}
display_prop_string_p (Lisp_Object prop, Lisp_Object string)
{
if (CONSP (prop)
- && CONSP (XCAR (prop))
- && !EQ (Qmargin, XCAR (XCAR (prop))))
+ && !EQ (XCAR (prop), Qwhen)
+ && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
{
/* A list of sub-properties. */
while (CONSP (prop))
/* When called from handle_stop, there might be an empty display
string loaded. In that case, don't bother saving it. */
if (!STRINGP (it->string) || SCHARS (it->string))
- push_it (it);
+ push_it (it, NULL);
/* Set up IT to deliver display elements from the first overlay
string. */
/* Save current settings of IT on IT->stack. Called, for example,
before setting up IT for an overlay string, to be able to restore
IT's settings to what they were after the overlay string has been
- processed. */
+ processed. If POSITION is non-NULL, it is the position to save on
+ the stack instead of IT->position. */
static void
-push_it (struct it *it)
+push_it (struct it *it, struct text_pos *position)
{
struct iterator_stack_entry *p;
p->u.stretch.object = it->object;
break;
}
- p->position = it->position;
+ p->position = position ? *position : it->position;
p->current = it->current;
p->end_charpos = it->end_charpos;
p->string_nchars = it->string_nchars;
{
it->bidi_it.first_elt = 1;
it->bidi_it.paragraph_dir = NEUTRAL_DIR;
+ it->bidi_it.disp_pos = -1;
}
if (set_stop_p)
if (CHAR_TABLE_P (Vglyphless_char_display)
&& CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
- glyphless_method = (c >= 0
- ? CHAR_TABLE_REF (Vglyphless_char_display, c)
- : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
+ {
+ if (c >= 0)
+ {
+ glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
+ if (CONSP (glyphless_method))
+ glyphless_method = FRAME_WINDOW_P (it->f)
+ ? XCAR (glyphless_method)
+ : XCDR (glyphless_method);
+ }
+ else
+ glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
+ }
+
retry:
if (NILP (glyphless_method))
{
/* Return the first character from the display table
entry, if not empty. If empty, don't display the
current character. */
- if (v->size)
+ if (v->header.size)
{
it->dpvec_char_len = it->len;
it->dpvec = v->contents;
- it->dpend = v->contents + v->size;
+ it->dpend = v->contents + v->header.size;
it->current.dpvec_index = 0;
it->dpvec_face_id = -1;
it->saved_face_id = it->face_id;
display. Then, set IT->dpvec to these glyphs. */
Lisp_Object gc;
int ctl_len;
- int face_id, lface_id = 0 ;
+ int face_id;
+ EMACS_INT lface_id = 0;
int escape_glyph;
/* Handle control characters with ^. */
}
}
-#ifdef HAVE_WINDOW_SYSTEM
/* Adjust face id for a multibyte character. There are no multibyte
character in unibyte text. */
if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
else
{
EMACS_INT pos = (it->s ? -1
- : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
- : IT_CHARPOS (*it));
+ : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
+ : IT_CHARPOS (*it));
+ int c;
+
+ if (it->what == IT_CHARACTER)
+ c = it->char_to_display;
+ else
+ {
+ struct composition *cmp = composition_table[it->cmp_it.id];
+ int i;
- it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
- it->string);
+ c = ' ';
+ for (i = 0; i < cmp->glyph_len; i++)
+ if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
+ break;
+ }
+ it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
}
}
-#endif
done:
/* Is this character the last one of a run of characters with
it->face_id = it->dpvec_face_id;
else
{
- int lface_id = GLYPH_CODE_FACE (gc);
+ EMACS_INT lface_id = GLYPH_CODE_FACE (gc);
if (lface_id > 0)
it->face_id = merge_faces (it->f, Qt, lface_id,
it->saved_face_id);
{
if (m)
{
- char *buf = FRAME_MESSAGE_BUF (f);
- size_t bufsize = FRAME_MESSAGE_BUF_SIZE (f);
- int len;
-
- memset (buf, 0, bufsize);
- len = vsnprintf (buf, bufsize, m, ap);
+ size_t len;
- /* Do any truncation at a character boundary. */
- if (! (0 <= len && len < bufsize))
- for (len = strnlen (buf, bufsize);
- len && ! CHAR_HEAD_P (buf[len - 1]);
- len--)
- continue;
+ len = doprnt (FRAME_MESSAGE_BUF (f),
+ FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
message2 (FRAME_MESSAGE_BUF (f), len, 0);
}
window_height_changed_p
= with_echo_area_buffer (w, display_last_displayed_message_p,
display_echo_area_1,
- (EMACS_INT) w, Qnil, 0, 0);
+ (intptr_t) w, Qnil, 0, 0);
if (no_message_p)
echo_area_buffer[i] = Qnil;
static int
display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
{
- struct window *w = (struct window *) a1;
+ intptr_t i1 = a1;
+ struct window *w = (struct window *) i1;
Lisp_Object window;
struct text_pos start;
int window_height_changed_p = 0;
resize_exactly = Qnil;
resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
- (EMACS_INT) w, resize_exactly, 0, 0);
+ (intptr_t) w, resize_exactly,
+ 0, 0);
if (resized_p)
{
++windows_or_buffers_changed;
static int
resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
{
- return resize_mini_window ((struct window *) a1, !NILP (exactly));
+ intptr_t i1 = a1;
+ return resize_mini_window ((struct window *) i1, !NILP (exactly));
}
else
{
with_echo_area_buffer (0, 0, current_message_1,
- (EMACS_INT) &msg, Qnil, 0, 0);
+ (intptr_t) &msg, Qnil, 0, 0);
if (NILP (msg))
echo_area_buffer[0] = Qnil;
}
static int
current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
{
- Lisp_Object *msg = (Lisp_Object *) a1;
+ intptr_t i1 = a1;
+ Lisp_Object *msg = (Lisp_Object *) i1;
if (Z > BEG)
*msg = make_buffer_string (BEG, Z, 1);
|| (STRINGP (string) && STRING_MULTIBYTE (string)));
with_echo_area_buffer (0, -1, set_message_1,
- (EMACS_INT) s, string, nbytes, multibyte_p);
+ (intptr_t) s, string, nbytes, multibyte_p);
message_buf_print = 0;
help_echo_showing_p = 0;
}
static int
set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
{
- const char *s = (const char *) a1;
+ intptr_t i1 = a1;
+ const char *s = (const char *) i1;
const unsigned char *msg = (const unsigned char *) s;
Lisp_Object string = a2;
buffer position, END is given as a distance from Z. Used in
redisplay_internal for display optimization. */
-static INLINE int
+static inline int
text_outside_line_unchanged_p (struct window *w,
EMACS_INT start, EMACS_INT end)
{
/* Reconsider the setting of B->clip_changed which is displayed
in window W. */
-static INLINE void
+static inline void
reconsider_clip_changes (struct window *w, struct buffer *b)
{
if (b->clip_changed
GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
positioned between POS_BEFORE and POS_AFTER in the
buffer. */
- struct glyph *stop = glyph_after;
+ struct glyph *start, *stop;
EMACS_INT pos = pos_before;
x = -1;
- for (glyph = glyph_before + incr;
+
+ /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
+ correspond to POS_BEFORE and POS_AFTER, respectively. We
+ need START and STOP in the order that corresponds to the
+ row's direction as given by its reversed_p flag. If the
+ directionality of characters between POS_BEFORE and
+ POS_AFTER is the opposite of the row's base direction,
+ these characters will have been reordered for display,
+ and we need to reverse START and STOP. */
+ if (!row->reversed_p)
+ {
+ start = min (glyph_before, glyph_after);
+ stop = max (glyph_before, glyph_after);
+ }
+ else
+ {
+ start = max (glyph_before, glyph_after);
+ stop = min (glyph_before, glyph_after);
+ }
+ for (glyph = start + incr;
row->reversed_p ? glyph > stop : glyph < stop; )
{
We assume that the window's buffer is really current. */
-static INLINE struct text_pos
+static inline struct text_pos
run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
{
struct window *w = XWINDOW (window);
return rc;
}
-static void
+#if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
+static
+#endif
+void
set_vertical_scroll_bar (struct window *w)
{
EMACS_INT start, end, whole;
/* If there is a scroll margin at the top of the window, find
its character position. */
- if (margin)
+ if (margin
+ /* Cannot call start_display if startp is not in the
+ accessible region of the buffer. This can happen when we
+ have just switched to a different buffer and/or changed
+ its restriction. In that case, startp is initialized to
+ the character position 1 (BEG) because we did not yet
+ have chance to display the buffer even once. */
+ && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
{
struct it it1;
&& EQ (FRAME_SELECTED_WINDOW (f), window))
{
int redisplay_menu_p = 0;
- int redisplay_tool_bar_p = 0;
if (FRAME_WINDOW_P (f))
{
if (FRAME_WINDOW_P (f))
{
#if defined (USE_GTK) || defined (HAVE_NS)
- redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
+ if (FRAME_EXTERNAL_TOOL_BAR (f))
+ redisplay_tool_bar (f);
#else
- redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
- && (FRAME_TOOL_BAR_LINES (f) > 0
- || !NILP (Vauto_resize_tool_bars));
+ if (WINDOWP (f->tool_bar_window)
+ && (FRAME_TOOL_BAR_LINES (f) > 0
+ || !NILP (Vauto_resize_tool_bars))
+ && redisplay_tool_bar (f))
+ ignore_mouse_drag_p = 1;
#endif
-
- if (redisplay_tool_bar_p && redisplay_tool_bar (f))
- {
- ignore_mouse_drag_p = 1;
- }
}
#endif
}
row->visible_height -= min_y - row->y;
if (row->y + row->height > max_y)
row->visible_height -= row->y + row->height - max_y;
- row->redraw_fringe_bitmaps_p = 1;
+ if (row->fringe_bitmap_periodic_p)
+ row->redraw_fringe_bitmaps_p = 1;
it.current_y += row->height;
row->visible_height -= min_y - row->y;
if (row->y + row->height > max_y)
row->visible_height -= row->y + row->height - max_y;
- row->redraw_fringe_bitmaps_p = 1;
+ if (row->fringe_bitmap_periodic_p)
+ row->redraw_fringe_bitmaps_p = 1;
}
/* Scroll the current matrix. */
}
-DEFUE ("dump-glyph-matrix", Fdump_glyph_matrix,
+DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
Sdump_glyph_matrix, 0, 1, "p",
doc: /* Dump the current matrix of the selected window to stderr.
Shows contents of glyph row structures. With non-nil
}
-DEFUE ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
+DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
(void)
{
}
-DEFUE ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
+DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
doc: /* Dump glyph row ROW to stderr.
GLYPH 0 means don't dump glyphs.
GLYPH 1 means dump glyphs in short form.
}
-DEFUE ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
+DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
GLYPH 0 means don't dump glyphs.
GLYPH 1 means dump glyphs in short form.
}
-DEFUE ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
+DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
doc: /* Toggle tracing of redisplay.
With ARG, turn tracing on if and only if ARG is positive. */)
(Lisp_Object arg)
}
-DEFUE ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
+DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
doc: /* Like `format', but print result to stderr.
usage: (trace-to-stderr STRING &rest OBJECTS) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
Lisp_Object s = Fformat (nargs, args);
fprintf (stderr, "%s", SDATA (s));
static int
push_display_prop (struct it *it, Lisp_Object prop)
{
- push_it (it);
+ push_it (it, NULL);
if (STRINGP (prop))
{
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;
/* Display all items of the menu bar. */
items = FRAME_MENU_BAR_ITEMS (it.f);
- for (i = 0; i < XVECTOR (items)->size; i += 4)
+ for (i = 0; i < ASIZE (items); i += 4)
{
Lisp_Object string;
else if (CHARACTERP (eoltype))
{
unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
- eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
+ int c = XFASTINT (eoltype);
+ eol_str_len = CHAR_STRING (c, tmp);
eol_str = tmp;
}
else
so get us a 2-digit number that is close. */
if (total == 100)
total = 99;
- sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
+ sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
return decode_mode_spec_buf;
}
}
if (total == 100)
total = 99;
if (toppos <= BUF_BEGV (b))
- sprintf (decode_mode_spec_buf, "Top%2ld%%", (long)total);
+ sprintf (decode_mode_spec_buf, "Top%2"pI"d%%", total);
else
- sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
+ sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
return decode_mode_spec_buf;
}
}
/* Append the list of glyph strings with head H and tail T to the list
with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
-static INLINE void
+static inline void
append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
struct glyph_string *h, struct glyph_string *t)
{
list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
result. */
-static INLINE void
+static inline void
prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
struct glyph_string *h, struct glyph_string *t)
{
/* Append glyph string S to the list with head *HEAD and tail *TAIL.
Set *HEAD and *TAIL to the resulting list. */
-static INLINE void
+static inline void
append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
struct glyph_string *s)
{
Value is a pointer to a realized face that is ready for display if
DISPLAY_P is non-zero. */
-static INLINE struct face *
+static inline struct face *
get_char_face_and_encoding (struct frame *f, int c, int face_id,
XChar2b *char2b, int display_p)
{
The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
a pointer to a realized face that is ready for display. */
-static INLINE struct face *
+static inline struct face *
get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
XChar2b *char2b, int *two_byte_p)
{
/* Get glyph code of character C in FONT in the two-byte form CHAR2B.
Retunr 1 if FONT has a glyph for C, otherwise return 0. */
-static INLINE int
+static inline int
get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
{
unsigned code;
first glyph following S. LAST_X is the right-most x-position + 1
in the drawing area. */
-static INLINE void
+static inline void
set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
{
/* If the face of this glyph string has to be drawn to the end of
/* Store one glyph for IT->char_to_display in IT->glyph_row.
Called from x_produce_glyphs when IT->glyph_row is non-null. */
-static INLINE void
+static inline void
append_glyph (struct it *it)
{
struct glyph *glyph;
IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
non-null. */
-static INLINE void
+static inline void
append_composite_glyph (struct it *it)
{
struct glyph *glyph;
/* Change IT->ascent and IT->height according to the setting of
IT->voffset. */
-static INLINE void
+static inline void
take_vertical_position_into_account (struct it *it)
{
if (it->voffset)
{
if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
+ if (CONSP (acronym))
+ acronym = XCAR (acronym);
str = STRINGP (acronym) ? SSDATA (acronym) : "";
}
else
int lbearing, rbearing;
int i, width, ascent, descent;
int left_padded = 0, right_padded = 0;
- int c;
+ int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
XChar2b char2b;
struct font_metrics *pcm;
int font_not_found_p;
/* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
and MSDOS. */
-void
+static void
draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
int start_hpos, int end_hpos,
enum draw_glyphs_face draw)
{
struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
Lisp_Object *poly = v->contents;
- int n = v->size;
+ int n = v->header.size;
int i;
int inside = 0;
Lisp_Object lx, ly;
{
result->x = right->x;
- /* The right end of the intersection is the minimum of the
+ /* The right end of the intersection is the minimum of
the right ends of left and right. */
result->width = (min (left->x + left->width, right->x + right->width)
- result->x);
Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
- doc: /* Char-table to control displaying of glyphless characters.
-Each element, if non-nil, is an ASCII acronym string (displayed in a box)
-or one of these symbols:
- hex-code: display the hexadecimal code of a character in a box
- empty-box: display as an empty box
- thin-space: display as 1-pixel width space
- zero-width: don't display
-
-It has one extra slot to control the display of a character for which
-no font is found. The value of the slot is `hex-code' or `empty-box'.
-The default is `empty-box'. */);
+ doc: /* Char-table defining glyphless characters.
+Each element, if non-nil, should be one of the following:
+ an ASCII acronym string: display this string in a box
+ `hex-code': display the hexadecimal code of a character in a box
+ `empty-box': display as an empty box
+ `thin-space': display as 1-pixel width space
+ `zero-width': don't display
+An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
+display method for graphical terminals and text terminals respectively.
+GRAPHICAL and TEXT should each have one of the values listed above.
+
+The char-table has one extra slot to control the display of a character for
+which no font is found. This slot only takes effect on graphical terminals.
+Its value should be an ASCII acronym string, `hex-code', `empty-box', or
+`thin-space'. The default is `empty-box'. */);
Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
Qempty_box);
void
init_xdisp (void)
{
- Lisp_Object root_window;
- struct window *mini_w;
-
current_header_line_height = current_mode_line_height = -1;
CHARPOS (this_line_start_pos) = 0;
- mini_w = XWINDOW (minibuf_window);
- root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
-
if (!noninteractive)
{
- struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
+ struct window *m = XWINDOW (minibuf_window);
+ Lisp_Object frame = m->frame;
+ struct frame *f = XFRAME (frame);
+ Lisp_Object root = FRAME_ROOT_WINDOW (f);
+ struct window *r = XWINDOW (root);
int i;
- XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
- set_window_height (root_window,
- FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
- 0);
- mini_w->top_line = make_number (FRAME_LINES (f) - 1);
- set_window_height (minibuf_window, 1, 0);
+ echo_area_window = minibuf_window;
- XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
- mini_w->total_cols = make_number (FRAME_COLS (f));
+ XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
+ XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
+ XSETFASTINT (r->total_cols, FRAME_COLS (f));
+ XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
+ XSETFASTINT (m->total_lines, 1);
+ XSETFASTINT (m->total_cols, FRAME_COLS (f));
scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
scratch_glyph_row.glyphs[TEXT_AREA + 1]