/* Display generation from window structure and buffer text.
-Copyright (C) 1985-1988, 1993-1995, 1997-2014 Free Software Foundation,
+Copyright (C) 1985-1988, 1993-1995, 1997-2015 Free Software Foundation,
Inc.
This file is part of GNU Emacs.
#define INFINITY 10000000
-Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
-Lisp_Object Qwindow_scroll_functions;
-static Lisp_Object Qwindow_text_change_functions;
-static Lisp_Object Qredisplay_end_trigger_functions;
-Lisp_Object Qinhibit_point_motion_hooks;
-static Lisp_Object QCeval, QCpropertize;
-Lisp_Object QCfile, QCdata;
-static Lisp_Object Qfontified;
-static Lisp_Object Qgrow_only;
-static Lisp_Object Qinhibit_eval_during_redisplay;
-static Lisp_Object Qbuffer_position, Qposition, Qobject;
-static Lisp_Object Qright_to_left, Qleft_to_right;
-
-/* Cursor shapes. */
-Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
-
-/* Pointer shapes. */
-static Lisp_Object Qarrow, Qhand;
-Lisp_Object Qtext;
-
/* Holds the list (error). */
static Lisp_Object list_of_error;
-static Lisp_Object Qfontification_functions;
-
-static Lisp_Object Qwrap_prefix;
-static Lisp_Object Qline_prefix;
-static Lisp_Object Qredisplay_internal;
-
-/* Non-nil means don't actually do any redisplay. */
-
-Lisp_Object Qinhibit_redisplay;
-
-/* Names of text properties relevant for redisplay. */
-
-Lisp_Object Qdisplay;
-
-Lisp_Object Qspace, QCalign_to;
-static Lisp_Object QCrelative_width, QCrelative_height;
-Lisp_Object Qleft_margin, Qright_margin;
-static Lisp_Object Qspace_width, Qraise;
-static Lisp_Object Qslice;
-Lisp_Object Qcenter;
-static Lisp_Object Qmargin, Qpointer;
-static Lisp_Object Qline_height;
-
#ifdef HAVE_WINDOW_SYSTEM
/* Test if overflow newline into fringe. Called with iterator IT
&& (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
|| *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
-/* Name of the face used to highlight trailing whitespace. */
-
-static Lisp_Object Qtrailing_whitespace;
-
-/* Name and number of the face used to highlight escape glyphs. */
-
-static Lisp_Object Qescape_glyph;
-
-/* Name and number of the face used to highlight non-breaking spaces. */
-
-static Lisp_Object Qnobreak_space;
-
-/* The symbol `image' which is the car of the lists used to represent
- images in Lisp. Also a tool bar style. */
-
-Lisp_Object Qimage;
-
-/* The image map types. */
-Lisp_Object QCmap;
-static Lisp_Object QCpointer;
-static Lisp_Object Qrect, Qcircle, Qpoly;
-
-/* Tool bar styles */
-Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
-
/* Non-zero means print newline to stdout before next mini-buffer
message. */
static struct buffer *this_line_buffer;
-
-/* Values of those variables at last redisplay are stored as
- properties on `overlay-arrow-position' symbol. However, if
- Voverlay_arrow_position is a marker, last-arrow-position is its
- numerical position. */
-
-static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
-
-/* Alternative overlay-arrow-string and overlay-arrow-bitmap
- properties on a symbol in overlay-arrow-variable-list. */
-
-static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
-
-Lisp_Object Qmenu_bar_update_hook;
-
/* Nonzero if an overlay arrow has been displayed in this window. */
static bool overlay_arrow_seen;
static bool message_buf_print;
-/* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
-
-static Lisp_Object Qinhibit_menubar_update;
-static Lisp_Object Qmessage_truncate_lines;
-
/* Set to 1 in clear_message to make redisplay_internal aware
of an emptied echo area. */
#define TRACE_MOVE(x) (void) 0
#endif
-static Lisp_Object Qauto_hscroll_mode;
-
/* Buffer being redisplayed -- for redisplay_window_error. */
static struct buffer *displayed_buffer;
struct props
{
- /* The name of the property. */
- Lisp_Object *name;
+ /* The symbol index of the name of the property. */
+ short name;
/* A unique index for the property. */
enum prop_idx idx;
static struct props it_props[] =
{
- {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
+ {SYMBOL_INDEX (Qfontified), FONTIFIED_PROP_IDX, handle_fontified_prop},
/* Handle `face' before `display' because some sub-properties of
`display' need to know the face. */
- {&Qface, FACE_PROP_IDX, handle_face_prop},
- {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
- {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
- {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
- {NULL, 0, NULL}
+ {SYMBOL_INDEX (Qface), FACE_PROP_IDX, handle_face_prop},
+ {SYMBOL_INDEX (Qdisplay), DISPLAY_PROP_IDX, handle_display_prop},
+ {SYMBOL_INDEX (Qinvisible), INVISIBLE_PROP_IDX, handle_invisible_prop},
+ {SYMBOL_INDEX (Qcomposition), COMPOSITION_PROP_IDX, handle_composition_prop},
+ {0, 0, NULL}
};
/* Value is the position described by X. If X is a marker, value is
bool redisplaying_p;
-static Lisp_Object Qinhibit_free_realized_faces;
-static Lisp_Object Qmode_line_default_help_echo;
-
/* If a string, XTread_socket generates an event to display that string.
(The display is done in read_char.) */
#endif /* HAVE_WINDOW_SYSTEM */
-/* Name of the face used to display glyphless characters. */
-static Lisp_Object Qglyphless_char;
-
-/* Symbol for the purpose of Vglyphless_char_display. */
-static Lisp_Object Qglyphless_char_display;
-
-/* Method symbols for Vglyphless_char_display. */
-static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
-
/* Default number of seconds to wait before displaying an hourglass
cursor. */
#define DEFAULT_HOURGLASS_DELAY 1
static void pop_it (struct it *);
static void sync_frame_with_window_matrix_rows (struct window *);
static void redisplay_internal (void);
-static int echo_area_display (int);
+static bool echo_area_display (bool);
static void redisplay_windows (Lisp_Object);
static void redisplay_window (Lisp_Object, bool);
static Lisp_Object redisplay_window_error (Lisp_Object);
struct text_pos top;
int visible_p = 0;
struct buffer *old_buffer = NULL;
+ bool r2l = false;
if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
return visible_p;
*rowh = max (0, (min (bottom_y, it.last_visible_y)
- max (top_y, window_top_y)));
*vpos = it.vpos;
+ if (it.bidi_it.paragraph_dir == R2L)
+ r2l = true;
}
}
else
- max (it2.current_y,
WINDOW_HEADER_LINE_HEIGHT (w))));
*vpos = it2.vpos;
+ if (it2.bidi_it.paragraph_dir == R2L)
+ r2l = true;
}
else
bidi_unshelve_cache (it2data, 1);
if (old_buffer)
set_buffer_internal_1 (old_buffer);
- if (visible_p && w->hscroll > 0)
- *x -=
- window_hscroll_limited (w, WINDOW_XFRAME (w))
- * WINDOW_FRAME_COLUMN_WIDTH (w);
+ if (visible_p)
+ {
+ if (w->hscroll > 0)
+ *x -=
+ window_hscroll_limited (w, WINDOW_XFRAME (w))
+ * WINDOW_FRAME_COLUMN_WIDTH (w);
+ /* For lines in an R2L paragraph, we need to mirror the X pixel
+ coordinate wrt the text area. For the reasons, see the
+ commentary in buffer_posn_from_coords and the explanation of
+ the geometry used by the move_it_* functions at the end of
+ the large commentary near the beginning of this file. */
+ if (r2l)
+ *x = window_box_width (w, TEXT_AREA) - *x - 1;
+ }
#if 0
/* Debugging code. */
glyph, and `x-stretch-block-cursor' is nil, don't draw a
rectangle as wide as the glyph, but use a canonical character
width instead. */
- wd = glyph->pixel_width - 1;
-#if defined (HAVE_NTGUI) || defined (HAVE_NS)
- wd++; /* Why? */
-#endif
+ wd = glyph->pixel_width;
x = w->phys_cursor.x;
if (x < 0)
return retval;
}
-static Lisp_Object Qeval;
-
Lisp_Object
safe_eval (Lisp_Object sexpr)
{
}
/* Clear IT. */
+ /* As a side effect, this sets it->object to nil, so verify we will
+ indeed get that. */
+ verify (NIL_IS_ZERO);
memset (it, 0, sizeof *it);
it->current.overlay_string_index = -1;
it->current.dpvec_index = -1;
/* Get properties here. */
for (p = it_props; p->handler; ++p)
- values_here[p->idx] = textget (iv->plist, *p->name);
+ values_here[p->idx] = textget (iv->plist,
+ builtin_lisp_symbol (p->name));
/* Look for an interval following iv that has different
properties. */
{
for (p = it_props; p->handler; ++p)
{
- Lisp_Object new_value;
-
- new_value = textget (next_iv->plist, *p->name);
+ Lisp_Object new_value = textget (next_iv->plist,
+ builtin_lisp_symbol (p->name));
if (!EQ (values_here[p->idx], new_value))
break;
}
iterate_out_of_display_property (it);
*position = it->position;
}
+ /* If we were to display this fringe bitmap,
+ next_element_from_image would have reset this flag.
+ Do the same, to avoid affecting overlays that
+ follow. */
+ it->ignore_overlay_strings_at_pos_p = 0;
return 1;
}
}
iterate_out_of_display_property (it);
*position = it->position;
}
+ if (it)
+ /* Reset this flag like next_element_from_image would. */
+ it->ignore_overlay_strings_at_pos_p = 0;
return 1;
}
is R..." */
/* FIXME: Do we need an exception for characters from display
tables? */
- if (it->bidi_p && it->bidi_it.type == STRONG_R)
+ if (it->bidi_p && it->bidi_it.type == STRONG_R
+ && !inhibit_bidi_mirroring)
it->c = bidi_mirror_char (it->c);
/* Map via display table or translate control characters.
IT->c, IT->len etc. have been set to the next character by
else if (it->cmp_it.id >= 0)
{
/* We are currently getting glyphs from a composition. */
- int i;
-
if (! it->bidi_p)
{
IT_CHARPOS (*it) += it->cmp_it.nchars;
IT_BYTEPOS (*it) += it->cmp_it.nbytes;
- if (it->cmp_it.to < it->cmp_it.nglyphs)
- {
- it->cmp_it.from = it->cmp_it.to;
- }
- else
- {
- it->cmp_it.id = -1;
- composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
- IT_BYTEPOS (*it),
- it->end_charpos, Qnil);
- }
}
- else if (! it->cmp_it.reversed_p)
+ else
{
- /* Composition created while scanning forward. */
+ int i;
+
/* Update IT's char/byte positions to point to the first
character of the next grapheme cluster, or to the
character visually after the current composition. */
bidi_move_to_visually_next (&it->bidi_it);
IT_BYTEPOS (*it) = it->bidi_it.bytepos;
IT_CHARPOS (*it) = it->bidi_it.charpos;
+ }
- if (it->cmp_it.to < it->cmp_it.nglyphs)
- {
- /* Proceed to the next grapheme cluster. */
- it->cmp_it.from = it->cmp_it.to;
- }
- else
- {
- /* No more grapheme clusters in this composition.
- Find the next stop position. */
- ptrdiff_t stop = it->end_charpos;
- if (it->bidi_it.scan_dir < 0)
- /* Now we are scanning backward and don't know
- where to stop. */
- stop = -1;
- composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
- IT_BYTEPOS (*it), stop, Qnil);
- }
+ if ((! it->bidi_p || ! it->cmp_it.reversed_p)
+ && it->cmp_it.to < it->cmp_it.nglyphs)
+ {
+ /* Composition created while scanning forward. Proceed
+ to the next grapheme cluster. */
+ it->cmp_it.from = it->cmp_it.to;
+ }
+ else if ((it->bidi_p && it->cmp_it.reversed_p)
+ && it->cmp_it.from > 0)
+ {
+ /* Composition created while scanning backward. Proceed
+ to the previous grapheme cluster. */
+ it->cmp_it.to = it->cmp_it.from;
}
else
{
- /* Composition created while scanning backward. */
- /* Update IT's char/byte positions to point to the last
- character of the previous grapheme cluster, or the
- character visually after the current composition. */
- for (i = 0; i < it->cmp_it.nchars; i++)
- bidi_move_to_visually_next (&it->bidi_it);
- IT_BYTEPOS (*it) = it->bidi_it.bytepos;
- IT_CHARPOS (*it) = it->bidi_it.charpos;
- if (it->cmp_it.from > 0)
- {
- /* Proceed to the previous grapheme cluster. */
- it->cmp_it.to = it->cmp_it.from;
- }
- else
- {
- /* No more grapheme clusters in this composition.
- Find the next stop position. */
- ptrdiff_t stop = it->end_charpos;
- if (it->bidi_it.scan_dir < 0)
- /* Now we are scanning backward and don't know
- where to stop. */
- stop = -1;
- composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
- IT_BYTEPOS (*it), stop, Qnil);
- }
+ /* No more grapheme clusters in this composition.
+ Find the next stop position. */
+ ptrdiff_t stop = it->end_charpos;
+
+ if (it->bidi_it.scan_dir < 0)
+ /* Now we are scanning backward and don't know
+ where to stop. */
+ stop = -1;
+ composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
+ IT_BYTEPOS (*it), stop, Qnil);
}
}
else
}
if (it->cmp_it.id >= 0)
{
- int i;
-
+ /* We are delivering display elements from a composition.
+ Update the string position past the grapheme cluster
+ we've just processed. */
if (! it->bidi_p)
{
IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
- if (it->cmp_it.to < it->cmp_it.nglyphs)
- it->cmp_it.from = it->cmp_it.to;
- else
- {
- it->cmp_it.id = -1;
- composition_compute_stop_pos (&it->cmp_it,
- IT_STRING_CHARPOS (*it),
- IT_STRING_BYTEPOS (*it),
- it->end_charpos, it->string);
- }
}
- else if (! it->cmp_it.reversed_p)
+ else
{
+ int i;
+
for (i = 0; i < it->cmp_it.nchars; i++)
bidi_move_to_visually_next (&it->bidi_it);
IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
+ }
- if (it->cmp_it.to < it->cmp_it.nglyphs)
- it->cmp_it.from = it->cmp_it.to;
- else
- {
- ptrdiff_t stop = it->end_charpos;
- if (it->bidi_it.scan_dir < 0)
- stop = -1;
- composition_compute_stop_pos (&it->cmp_it,
- IT_STRING_CHARPOS (*it),
- IT_STRING_BYTEPOS (*it), stop,
- it->string);
- }
+ /* Did we exhaust all the grapheme clusters of this
+ composition? */
+ if ((! it->bidi_p || ! it->cmp_it.reversed_p)
+ && (it->cmp_it.to < it->cmp_it.nglyphs))
+ {
+ /* Not all the grapheme clusters were processed yet;
+ advance to the next cluster. */
+ it->cmp_it.from = it->cmp_it.to;
+ }
+ else if ((it->bidi_p && it->cmp_it.reversed_p)
+ && it->cmp_it.from > 0)
+ {
+ /* Likewise: advance to the next cluster, but going in
+ the reverse direction. */
+ it->cmp_it.to = it->cmp_it.from;
}
else
{
- for (i = 0; i < it->cmp_it.nchars; i++)
- bidi_move_to_visually_next (&it->bidi_it);
- IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
- IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
- if (it->cmp_it.from > 0)
- it->cmp_it.to = it->cmp_it.from;
- else
+ /* This composition was fully processed; find the next
+ candidate place for checking for composed
+ characters. */
+ /* Always limit string searches to the string length;
+ any padding spaces are not part of the string, and
+ there cannot be any compositions in that padding. */
+ ptrdiff_t stop = SCHARS (it->string);
+
+ if (it->bidi_p && it->bidi_it.scan_dir < 0)
+ stop = -1;
+ else if (it->end_charpos < stop)
{
- ptrdiff_t stop = it->end_charpos;
- if (it->bidi_it.scan_dir < 0)
- stop = -1;
- composition_compute_stop_pos (&it->cmp_it,
- IT_STRING_CHARPOS (*it),
- IT_STRING_BYTEPOS (*it), stop,
- it->string);
+ /* Cf. PRECISION in reseat_to_string: we might be
+ limited in how many of the string characters we
+ need to deliver. */
+ stop = it->end_charpos;
}
+ composition_compute_stop_pos (&it->cmp_it,
+ IT_STRING_CHARPOS (*it),
+ IT_STRING_BYTEPOS (*it), stop,
+ it->string);
}
}
else
bidi_move_to_visually_next (&it->bidi_it);
IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
+ /* If the scan direction changes, we may need to update
+ the place where to check for composed characters. */
if (prev_scan_dir != it->bidi_it.scan_dir)
{
- ptrdiff_t stop = it->end_charpos;
+ ptrdiff_t stop = SCHARS (it->string);
if (it->bidi_it.scan_dir < 0)
stop = -1;
+ else if (it->end_charpos < stop)
+ stop = it->end_charpos;
+
composition_compute_stop_pos (&it->cmp_it,
IT_STRING_CHARPOS (*it),
IT_STRING_BYTEPOS (*it), stop,
eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
it->what = IT_CHARACTER;
BYTEPOS (it->position) = CHARPOS (it->position) = 0;
- it->object = Qnil;
+ it->object = make_number (0);
/* With bidi reordering, the character to display might not be the
character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
unsigned char *p;
ptrdiff_t stop;
+ /* We moved to the next buffer position, so any info about
+ previously seen overlays is no longer valid. */
+ it->ignore_overlay_strings_at_pos_p = 0;
+
/* Maybe run the redisplay end trigger hook. Performance note:
This doesn't seem to cost measurable time. */
if (it->redisplay_end_trigger_charpos
doesn't fit on the line, e.g. a wide image. */
it->hpos == 0
|| (new_x == it->last_visible_x
- && FRAME_WINDOW_P (it->f)
- /* When word-wrap is ON and we have a valid
- wrap point, we don't allow the last glyph
- to "just barely fit" on the line. */
- && (it->line_wrap != WORD_WRAP
- || wrap_it.sp < 0)))
+ && FRAME_WINDOW_P (it->f)))
{
++it->hpos;
it->current_x = new_x;
}
if (ITERATOR_AT_END_OF_LINE_P (it)
&& (it->line_wrap != WORD_WRAP
- || wrap_it.sp < 0))
+ || wrap_it.sp < 0
+ || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
{
result = MOVE_NEWLINE_OR_CR;
break;
else
clear_message (true, true);
- do_pending_window_change (0);
- echo_area_display (1);
- do_pending_window_change (0);
+ do_pending_window_change (false);
+ echo_area_display (true);
+ do_pending_window_change (false);
if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
(*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
}
is non-zero update selected_frame. Value is non-zero if the
mini-windows height has been changed. */
-static int
-echo_area_display (int update_frame_p)
+static bool
+echo_area_display (bool update_frame_p)
{
Lisp_Object mini_window;
struct window *w;
struct frame *f;
- int window_height_changed_p = 0;
+ bool window_height_changed_p = false;
struct frame *sf = SELECTED_FRAME ();
mini_window = FRAME_MINIBUF_WINDOW (sf);
/* Window configuration is the same as before.
Can do with a display update of the echo area,
unless we displayed some mode lines. */
- update_single_window (w, 1);
+ update_single_window (w);
flush_frame (f);
}
else
- update_frame (f, 1, 1);
+ update_frame (f, true, true);
/* If cursor is in the echo area, make sure that the next
redisplay displays the minibuffer, so that the cursor will
menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
#ifdef HAVE_WINDOW_SYSTEM
update_tool_bar (f, 0);
-#endif
-#ifdef HAVE_NS
- if (windows_or_buffers_changed
- && FRAME_NS_P (f))
- ns_set_doc_edited
- (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
#endif
UNGCPRO;
}
if (new_height != WINDOW_PIXEL_HEIGHT (w))
{
x_change_tool_bar_height (f, new_height);
+ frame_default_tool_bar_height = new_height;
/* Always do that now. */
clear_glyph_matrix (w->desired_matrix);
f->fonts_changed = 1;
if (change_height_p)
{
x_change_tool_bar_height (f, new_height);
+ frame_default_tool_bar_height = new_height;
clear_glyph_matrix (w->desired_matrix);
f->n_tool_bar_rows = nrows;
f->fonts_changed = 1;
struct window *w = XWINDOW (selected_window);
struct window *sw;
struct frame *fr;
- int pending;
+ bool pending;
bool must_finish = 0, match_p;
struct text_pos tlbufpos, tlendpos;
int number_of_visible_frames;
specbind (Qinhibit_free_realized_faces, Qnil);
/* Record this function, so it appears on the profiler's backtraces. */
- record_in_backtrace (Qredisplay_internal, &Qnil, 0);
+ record_in_backtrace (Qredisplay_internal, 0, 0);
FOR_EACH_FRAME (tail, frame)
XFRAME (frame)->already_hscrolled_p = 0;
/* Remember the currently selected window. */
sw = w;
- pending = 0;
+ pending = false;
last_escape_glyph_frame = NULL;
last_escape_glyph_face_id = (1 << FACE_ID_BITS);
last_glyphless_glyph_frame = NULL;
}
/* Notice any pending interrupt request to change frame size. */
- do_pending_window_change (1);
+ do_pending_window_change (true);
/* do_pending_window_change could change the selected_window due to
frame resizing which makes the selected window too small. */
echo-area doesn't show through. */
&& !MINI_WINDOW_P (XWINDOW (selected_window))))
{
- int window_height_changed_p = echo_area_display (0);
+ int window_height_changed_p = echo_area_display (false);
if (message_cleared_p)
update_miniwindow_p = true;
{
if (!must_finish)
{
- do_pending_window_change (1);
+ do_pending_window_change (true);
/* If selected_window changed, redisplay again. */
if (WINDOWP (selected_window)
&& (w = XWINDOW (selected_window)) != sw)
retry_frame:
+#if defined (HAVE_WINDOW_SYSTEM) && !defined (USE_GTK) && !defined (HAVE_NS)
+ /* Redisplay internal tool bar if this is the first time so we
+ can adjust the frame height right now, if necessary. */
+ if (!f->tool_bar_redisplayed_once)
+ {
+ if (redisplay_tool_bar (f))
+ adjust_frame_glyphs (f);
+ f->tool_bar_redisplayed_once = true;
+ }
+#endif
+
if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
{
bool gcscrollbars
if (f->fonts_changed)
{
adjust_frame_glyphs (f);
- f->fonts_changed = 0;
+ f->fonts_changed = false;
goto retry_frame;
}
/* See if we have to hscroll. */
if (!f->already_hscrolled_p)
{
- f->already_hscrolled_p = 1;
+ f->already_hscrolled_p = true;
if (hscroll_windows (f->root_window))
goto retry_frame;
}
unrequest_sigio ();
STOP_POLLING;
- pending |= update_frame (f, 0, 0);
- f->cursor_type_changed = 0;
- f->updated_p = 1;
+ pending |= update_frame (f, false, false);
+ f->cursor_type_changed = false;
+ f->updated_p = true;
}
}
}
goto retry;
XWINDOW (selected_window)->must_be_updated_p = true;
- pending = update_frame (sf, 0, 0);
- sf->cursor_type_changed = 0;
+ pending = update_frame (sf, false, false);
+ sf->cursor_type_changed = false;
}
/* We may have called echo_area_display at the top of this
if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
{
XWINDOW (mini_window)->must_be_updated_p = true;
- pending |= update_frame (mini_frame, 0, 0);
- mini_frame->cursor_type_changed = 0;
+ pending |= update_frame (mini_frame, false, false);
+ mini_frame->cursor_type_changed = false;
if (!pending && hscroll_windows (mini_window))
goto retry;
}
}
/* Change frame size now if a change is pending. */
- do_pending_window_change (1);
+ do_pending_window_change (true);
/* If we just did a pending size change, or have additional
visible frames, or selected_window changed, redisplay again. */
if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
{
- clear_face_cache (0);
+ clear_face_cache (false);
clear_face_cache_count = 0;
}
#endif /* HAVE_WINDOW_SYSTEM */
end_of_redisplay:
+#ifdef HAVE_NS
+ ns_set_doc_edited ();
+#endif
if (interrupt_input && interrupts_deferred)
request_sigio ();
{
/* We have a previously displayed message, but no current
message. Redisplay the previous message. */
- display_last_displayed_message_p = 1;
+ display_last_displayed_message_p = true;
redisplay_internal ();
- display_last_displayed_message_p = 0;
+ display_last_displayed_message_p = false;
}
else
redisplay_internal ();
if (!row->reversed_p)
{
while (glyph < end
- && INTEGERP (glyph->object)
+ && NILP (glyph->object)
&& glyph->charpos < 0)
{
x += glyph->pixel_width;
++glyph;
}
while (end > glyph
- && INTEGERP ((end - 1)->object)
+ && NILP ((end - 1)->object)
/* CHARPOS is zero for blanks and stretch glyphs
inserted by extend_face_to_end_of_line. */
&& (end - 1)->charpos <= 0)
glyph += row->used[TEXT_AREA] - 1;
while (glyph > end + 1
- && INTEGERP (glyph->object)
+ && NILP (glyph->object)
&& glyph->charpos < 0)
{
--glyph;
x -= glyph->pixel_width;
}
- if (INTEGERP (glyph->object) && glyph->charpos < 0)
+ if (NILP (glyph->object) && glyph->charpos < 0)
--glyph;
/* By default, in reversed rows we put the cursor on the
rightmost (first in the reading order) glyph. */
for (g = end + 1; g < glyph; g++)
x += g->pixel_width;
while (end < glyph
- && INTEGERP ((end + 1)->object)
+ && NILP ((end + 1)->object)
&& (end + 1)->charpos <= 0)
++end;
glyph_before = glyph + 1;
while (/* not marched to end of glyph row */
glyph < end
/* glyph was not inserted by redisplay for internal purposes */
- && !INTEGERP (glyph->object))
+ && !NILP (glyph->object))
{
if (BUFFERP (glyph->object))
{
++glyph;
}
else if (glyph > end) /* row is reversed */
- while (!INTEGERP (glyph->object))
+ while (!NILP (glyph->object))
{
if (BUFFERP (glyph->object))
{
&& BUFFERP (glyph->object) && glyph->charpos == pt_old)
&& !(bpos_max <= pt_old && pt_old <= bpos_covered))
{
- /* An empty line has a single glyph whose OBJECT is zero and
+ /* An empty line has a single glyph whose OBJECT is nil and
whose CHARPOS is the position of a newline on that line.
Note that on a TTY, there are more glyphs after that, which
were produced by extend_face_to_end_of_line, but their
CHARPOS is zero or negative. */
int empty_line_p =
(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
- && INTEGERP (glyph->object) && glyph->charpos > 0
+ && NILP (glyph->object) && glyph->charpos > 0
/* On a TTY, continued and truncated rows also have a glyph at
- their end whose OBJECT is zero and whose CHARPOS is
+ their end whose OBJECT is nil and whose CHARPOS is
positive (the continuation and truncation glyphs), but such
rows are obviously not "empty". */
&& !(row->continued_p || row->truncated_on_right_p);
&& string_from_text_prop)
/* this candidate is from newline and its
position is not an exact match */
- || (INTEGERP (glyph->object)
+ || (NILP (glyph->object)
&& glyph->charpos != pt_old)))))
return 0;
/* If this candidate gives an exact match, use that. */
terminating newline of a line, and point is on that
newline, it wins because it's an exact match. */
|| (!row->continued_p
- && INTEGERP (glyph->object)
+ && NILP (glyph->object)
&& glyph->charpos == 0
&& pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
/* Otherwise, keep the candidate that comes from a row
non-zero margins, because scroll_up_aggressively
means put point that fraction of window height
_from_the_bottom_margin_. */
- if (aggressive_scroll + 2*this_scroll_margin > height)
- aggressive_scroll = height - 2*this_scroll_margin;
+ if (aggressive_scroll + 2 * this_scroll_margin > height)
+ aggressive_scroll = height - 2 * this_scroll_margin;
amount_to_scroll = dy + aggressive_scroll;
}
}
start_display (&it, w, startp);
if (arg_scroll_conservatively)
- amount_to_scroll = max (dy, frame_line_height *
- max (scroll_step, temp_scroll_step));
+ amount_to_scroll = max (dy, frame_line_height
+ * max (scroll_step, temp_scroll_step));
else if (scroll_step || temp_scroll_step)
amount_to_scroll = scroll_max;
else
bottom of the window, if the value of
scroll_down_aggressively happens to be too
large. */
- if (aggressive_scroll + 2*this_scroll_margin > height)
- aggressive_scroll = height - 2*this_scroll_margin;
+ if (aggressive_scroll + 2 * this_scroll_margin > height)
+ aggressive_scroll = height - 2 * this_scroll_margin;
amount_to_scroll = dy + aggressive_scroll;
}
}
exact_match_p =
(BUFFERP (g->object) && g->charpos == PT)
- || (INTEGERP (g->object)
+ || (NILP (g->object)
&& (g->charpos == PT
|| (g->charpos == 0 && endpos - 1 == PT)));
}
set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
- /* If we are highlighting the region, then we just changed
- the region, so redisplay to show it. */
- /* FIXME: We need to (re)run pre-redisplay-function! */
- /* if (markpos_of_region () >= 0)
+ /* Re-run pre-redisplay-function so it can update the region
+ according to the new position of point. */
+ /* Other than the cursor, w's redisplay is done so we can set its
+ redisplay to false. Also the buffer's redisplay can be set to
+ false, since propagate_buffer_redisplay should have already
+ propagated its info to `w' anyway. */
+ w->redisplay = false;
+ XBUFFER (w->contents)->text->redisplay = false;
+ safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
+
+ if (w->redisplay || XBUFFER (w->contents)->text->redisplay)
{
+ /* pre-redisplay-function made changes (e.g. move the region)
+ that require another round of redisplay. */
clear_glyph_matrix (w->desired_matrix);
if (!try_window (window, startp, 0))
goto need_larger_matrices;
}
- */
}
if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, 0, 0))
{
{
int window_total_lines
= WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
- int margin =
- scroll_margin > 0
+ int margin
+ = scroll_margin > 0
? min (scroll_margin, window_total_lines / 4)
: 0;
ptrdiff_t margin_pos = CHARPOS (startp);
? 'B'
: (STRINGP (glyph->object)
? 'S'
- : (INTEGERP (glyph->object)
+ : (NILP (glyph->object)
? '0'
: '-'))),
glyph->pixel_width,
? 'B'
: (STRINGP (glyph->object)
? 'S'
- : (INTEGERP (glyph->object)
+ : (NILP (glyph->object)
? '0'
: '-'))),
glyph->pixel_width,
? 'B'
: (STRINGP (glyph->object)
? 'S'
- : (INTEGERP (glyph->object)
+ : (NILP (glyph->object)
? '0'
: '-'))),
glyph->pixel_width,
? 'B'
: (STRINGP (glyph->object)
? 'S'
- : (INTEGERP (glyph->object)
+ : (NILP (glyph->object)
? '0'
: '-'))),
glyph->pixel_width,
struct glyph *glyph = row->glyphs[area] + i;
if (i == row->used[area] - 1
&& area == TEXT_AREA
- && INTEGERP (glyph->object)
+ && NILP (glyph->object)
&& glyph->type == CHAR_GLYPH
&& glyph->u.ch == ' ')
{
doc: /* Dump the current matrix of the selected window to stderr.
Shows contents of glyph row structures. With non-nil
parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
-glyphs in short form, otherwise show glyphs in long form. */)
+glyphs in short form, otherwise show glyphs in long form.
+
+Interactively, no argument means show glyphs in short form;
+with numeric argument, its value is passed as the GLYPHS flag. */)
(Lisp_Object glyphs)
{
struct window *w = XWINDOW (selected_window);
DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
- Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
+ Sdump_frame_glyph_matrix, 0, 0, "", doc: /* Dump the current glyph matrix of the selected frame to stderr.
+Only text-mode frames have frame glyph matrices. */)
(void)
{
struct frame *f = XFRAME (selected_frame);
- dump_glyph_matrix (f->current_matrix, 1);
+
+ if (f->current_matrix)
+ dump_glyph_matrix (f->current_matrix, 1);
+ else
+ fprintf (stderr, "*** This frame doesn't have a frame glyph matrix ***\n");
return Qnil;
}
truncate_it.area = TEXT_AREA;
truncate_it.glyph_row->used[TEXT_AREA] = 0;
CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
- truncate_it.object = make_number (0);
+ truncate_it.object = Qnil;
produce_special_glyphs (&truncate_it, IT_TRUNCATION);
/* Overwrite glyphs from IT with truncation glyphs. */
it->what = IT_CHARACTER;
memset (&it->position, 0, sizeof it->position);
- it->object = make_number (0);
+ it->object = Qnil;
it->c = it->char_to_display = ' ';
it->len = 1;
else
it->face_id = face->id;
it->start_of_box_run_p = 0;
- append_stretch_glyph (it, make_number (0), stretch_width,
+ append_stretch_glyph (it, Qnil, stretch_width,
it->ascent + it->descent, stretch_ascent);
it->position = saved_pos;
it->avoid_cursor_p = saved_avoid_cursor;
it->what = IT_CHARACTER;
memset (&it->position, 0, sizeof it->position);
- it->object = make_number (0);
+ it->object = Qnil;
it->c = it->char_to_display = ' ';
it->len = 1;
{
while (glyph >= start
&& glyph->type == CHAR_GLYPH
- && INTEGERP (glyph->object))
+ && NILP (glyph->object))
--glyph;
}
else
{
while (glyph <= start
&& glyph->type == CHAR_GLYPH
- && INTEGERP (glyph->object))
+ && NILP (glyph->object))
++glyph;
}
{
start = r1->glyphs[TEXT_AREA];
end = start + r1->used[TEXT_AREA];
- /* Glyphs inserted by redisplay have an integer (zero)
- as their object. */
+ /* Glyphs inserted by redisplay have nil as their object. */
while (end > start
- && INTEGERP ((end - 1)->object)
+ && NILP ((end - 1)->object)
&& (end - 1)->charpos <= 0)
--end;
if (end > start)
end = r1->glyphs[TEXT_AREA] - 1;
start = end + r1->used[TEXT_AREA];
while (end < start
- && INTEGERP ((end + 1)->object)
+ && NILP ((end + 1)->object)
&& (end + 1)->charpos <= 0)
++end;
if (end < start)
{
/* If line-wrap is on, check if a previous
wrap point was found. */
- if (wrap_row_used > 0
+ if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
+ && wrap_row_used > 0
/* Even if there is a previous wrap
point, continue the line here as
usual, if (i) the previous character
row->continued_p = 0;
row->exact_window_width_line_p = 1;
}
+ /* If line-wrap is on, check if a
+ previous wrap point was found. */
+ else if (wrap_row_used > 0
+ /* Even if there is a previous wrap
+ point, continue the line here as
+ usual, if (i) the previous character
+ was a space or tab AND (ii) the
+ current character is not. */
+ && (!may_wrap
+ || IT_DISPLAYING_WHITESPACE (it)))
+ goto back_to_wrap;
+
}
}
else if (it->bidi_p)
}
}
+DEFUN ("bidi-find-overridden-directionality",
+ Fbidi_find_overridden_directionality,
+ Sbidi_find_overridden_directionality, 2, 3, 0,
+ doc: /* Return position between FROM and TO where directionality was overridden.
+
+This function returns the first character position in the specified
+region of OBJECT where there is a character whose `bidi-class' property
+is `L', but which was forced to display as `R' by a directional
+override, and likewise with characters whose `bidi-class' is `R'
+or `AL' that were forced to display as `L'.
+
+If no such character is found, the function returns nil.
+
+OBJECT is a Lisp string or buffer to search for overridden
+directionality, and defaults to the current buffer if nil or omitted.
+OBJECT can also be a window, in which case the function will search
+the buffer displayed in that window. Passing the window instead of
+a buffer is preferable when the buffer is displayed in some window,
+because this function will then be able to correctly account for
+window-specific overlays, which can affect the results.
+
+Strong directional characters `L', `R', and `AL' can have their
+intrinsic directionality overridden by directional override
+control characters RLO \(u+202e) and LRO \(u+202d). See the
+function `get-char-code-property' for a way to inquire about
+the `bidi-class' property of a character. */)
+ (Lisp_Object from, Lisp_Object to, Lisp_Object object)
+{
+ struct buffer *buf = current_buffer;
+ struct buffer *old = buf;
+ struct window *w = NULL;
+ bool frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ());
+ struct bidi_it itb;
+ ptrdiff_t from_pos, to_pos, from_bpos;
+ void *itb_data;
+
+ if (!NILP (object))
+ {
+ if (BUFFERP (object))
+ buf = XBUFFER (object);
+ else if (WINDOWP (object))
+ {
+ w = decode_live_window (object);
+ buf = XBUFFER (w->contents);
+ frame_window_p = FRAME_WINDOW_P (XFRAME (w->frame));
+ }
+ else
+ CHECK_STRING (object);
+ }
+
+ if (STRINGP (object))
+ {
+ /* Characters in unibyte strings are always treated by bidi.c as
+ strong LTR. */
+ if (!STRING_MULTIBYTE (object)
+ /* When we are loading loadup.el, the character property
+ tables needed for bidi iteration are not yet
+ available. */
+ || !NILP (Vpurify_flag))
+ return Qnil;
+
+ validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
+ if (from_pos >= SCHARS (object))
+ return Qnil;
+
+ /* Set up the bidi iterator. */
+ itb_data = bidi_shelve_cache ();
+ itb.paragraph_dir = NEUTRAL_DIR;
+ itb.string.lstring = object;
+ itb.string.s = NULL;
+ itb.string.schars = SCHARS (object);
+ itb.string.bufpos = 0;
+ itb.string.from_disp_str = 0;
+ itb.string.unibyte = 0;
+ itb.w = w;
+ bidi_init_it (0, 0, frame_window_p, &itb);
+ }
+ else
+ {
+ /* Nothing this fancy can happen in unibyte buffers, or in a
+ buffer that disabled reordering, or if FROM is at EOB. */
+ if (NILP (BVAR (buf, bidi_display_reordering))
+ || NILP (BVAR (buf, enable_multibyte_characters))
+ /* When we are loading loadup.el, the character property
+ tables needed for bidi iteration are not yet
+ available. */
+ || !NILP (Vpurify_flag))
+ return Qnil;
+
+ set_buffer_temp (buf);
+ validate_region (&from, &to);
+ from_pos = XINT (from);
+ to_pos = XINT (to);
+ if (from_pos >= ZV)
+ return Qnil;
+
+ /* Set up the bidi iterator. */
+ itb_data = bidi_shelve_cache ();
+ from_bpos = CHAR_TO_BYTE (from_pos);
+ if (from_pos == BEGV)
+ {
+ itb.charpos = BEGV;
+ itb.bytepos = BEGV_BYTE;
+ }
+ else if (FETCH_CHAR (from_bpos - 1) == '\n')
+ {
+ itb.charpos = from_pos;
+ itb.bytepos = from_bpos;
+ }
+ else
+ itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos),
+ -1, &itb.bytepos);
+ itb.paragraph_dir = NEUTRAL_DIR;
+ itb.string.s = NULL;
+ itb.string.lstring = Qnil;
+ itb.string.bufpos = 0;
+ itb.string.from_disp_str = 0;
+ itb.string.unibyte = 0;
+ itb.w = w;
+ bidi_init_it (itb.charpos, itb.bytepos, frame_window_p, &itb);
+ }
+
+ ptrdiff_t found;
+ do {
+ /* For the purposes of this function, the actual base direction of
+ the paragraph doesn't matter, so just set it to L2R. */
+ bidi_paragraph_init (L2R, &itb, 0);
+ while ((found = bidi_find_first_overridden (&itb)) < from_pos)
+ ;
+ } while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
+
+ bidi_unshelve_cache (itb_data, 0);
+ set_buffer_temp (old);
+
+ return (from_pos <= found && found < to_pos) ? make_number (found) : Qnil;
+}
+
DEFUN ("move-point-visually", Fmove_point_visually,
Smove_point_visually, 1, 1, 0,
doc: /* Move point in the visual order in the specified DIRECTION.
#define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
(!(ROW)->continued_p \
- && INTEGERP ((GLYPH)->object) \
+ && NILP ((GLYPH)->object) \
&& (GLYPH)->type == CHAR_GLYPH \
&& (GLYPH)->u.ch == ' ' \
&& (GLYPH)->charpos >= 0 \
w->cursor.vpos = -1;
return make_number (PT);
}
- else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
+ else if (!NILP (g->object) && !EQ (g->object, gpt->object))
{
ptrdiff_t new_pos;
return make_number (PT);
}
}
- if (g == e || INTEGERP (g->object))
+ if (g == e || NILP (g->object))
{
if (row->truncated_on_left_p || row->truncated_on_right_p)
goto simulate_display;
EOB also has one glyph, but its charpos is -1. */
|| (row->ends_at_zv_p
&& !row->reversed_p
- && INTEGERP (g->object)
+ && NILP (g->object)
&& g->type == CHAR_GLYPH
&& g->u.ch == ' '))
{
|| g->type == STRETCH_GLYPH
|| (row->ends_at_zv_p
&& row->reversed_p
- && INTEGERP (g->object)
+ && NILP (g->object)
&& g->type == CHAR_GLYPH
&& g->u.ch == ' '))
{
#undef ROW_GLYPH_NEWLINE_P
}
+DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
+ Sbidi_resolved_levels, 0, 1, 0,
+ doc: /* Return the resolved bidirectional levels of characters at VPOS.
+
+The resolved levels are produced by the Emacs bidi reordering engine
+that implements the UBA, the Unicode Bidirectional Algorithm. Please
+read the Unicode Standard Annex 9 (UAX#9) for background information
+about these levels.
+
+VPOS is the zero-based number of the current window's screen line
+for which to produce the resolved levels. If VPOS is nil or omitted,
+it defaults to the screen line of point. If the window displays a
+header line, VPOS of zero will report on the header line, and first
+line of text in the window will have VPOS of 1.
+
+Value is an array of resolved levels, indexed by glyph number.
+Glyphs are numbered from zero starting from the beginning of the
+screen line, i.e. the left edge of the window for left-to-right lines
+and from the right edge for right-to-left lines. The resolved levels
+are produced only for the window's text area; text in display margins
+is not included.
+
+If the selected window's display is not up-to-date, or if the specified
+screen line does not display text, this function returns nil. It is
+highly recommended to bind this function to some simple key, like F8,
+in order to avoid these problems.
+
+This function exists mainly for testing the correctness of the
+Emacs UBA implementation, in particular with the test suite. */)
+ (Lisp_Object vpos)
+{
+ struct window *w = XWINDOW (selected_window);
+ struct buffer *b = XBUFFER (w->contents);
+ int nrow;
+ struct glyph_row *row;
+
+ if (NILP (vpos))
+ {
+ int d1, d2, d3, d4, d5;
+
+ pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
+ }
+ else
+ {
+ CHECK_NUMBER_COERCE_MARKER (vpos);
+ nrow = XINT (vpos);
+ }
+
+ /* We require up-to-date glyph matrix for this window. */
+ if (w->window_end_valid
+ && !windows_or_buffers_changed
+ && b
+ && !b->clip_changed
+ && !b->prevent_redisplay_optimizations_p
+ && !window_outdated (w)
+ && nrow >= 0
+ && nrow < w->current_matrix->nrows
+ && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
+ && MATRIX_ROW_DISPLAYS_TEXT_P (row))
+ {
+ struct glyph *g, *e, *g1;
+ int nglyphs, i;
+ Lisp_Object levels;
+
+ if (!row->reversed_p) /* Left-to-right glyph row. */
+ {
+ g = g1 = row->glyphs[TEXT_AREA];
+ e = g + row->used[TEXT_AREA];
+
+ /* Skip over glyphs at the start of the row that was
+ generated by redisplay for its own needs. */
+ while (g < e
+ && NILP (g->object)
+ && g->charpos < 0)
+ g++;
+ g1 = g;
+
+ /* Count the "interesting" glyphs in this row. */
+ for (nglyphs = 0; g < e && !NILP (g->object); g++)
+ nglyphs++;
+
+ /* Create and fill the array. */
+ levels = make_uninit_vector (nglyphs);
+ for (i = 0; g1 < g; i++, g1++)
+ ASET (levels, i, make_number (g1->resolved_level));
+ }
+ else /* Right-to-left glyph row. */
+ {
+ g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
+ e = row->glyphs[TEXT_AREA] - 1;
+ while (g > e
+ && NILP (g->object)
+ && g->charpos < 0)
+ g--;
+ g1 = g;
+ for (nglyphs = 0; g > e && !NILP (g->object); g--)
+ nglyphs++;
+ levels = make_uninit_vector (nglyphs);
+ for (i = 0; g1 > g; i++, g1--)
+ ASET (levels, i, make_number (g1->resolved_level));
+ }
+ return levels;
+ }
+ else
+ return Qnil;
+}
+
+
\f
/***********************************************************************
Menu Bar
if (it->bidi_p)
{
glyph->resolved_level = it->bidi_it.resolved_level;
- if ((it->bidi_it.type & 7) != it->bidi_it.type)
- emacs_abort ();
+ eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
glyph->bidi_type = it->bidi_it.type;
}
else
if (it->bidi_p)
{
glyph->resolved_level = it->bidi_it.resolved_level;
- if ((it->bidi_it.type & 7) != it->bidi_it.type)
- emacs_abort ();
+ eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
glyph->bidi_type = it->bidi_it.type;
}
++it->glyph_row->used[area];
if (it->bidi_p)
{
glyph->resolved_level = it->bidi_it.resolved_level;
- if ((it->bidi_it.type & 7) != it->bidi_it.type)
- emacs_abort ();
+ eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
glyph->bidi_type = it->bidi_it.type;
}
++it->glyph_row->used[area];
if (it->bidi_p)
{
glyph->resolved_level = it->bidi_it.resolved_level;
- if ((it->bidi_it.type & 7) != it->bidi_it.type)
- emacs_abort ();
+ eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
glyph->bidi_type = it->bidi_it.type;
}
else
GLYPH glyph;
temp_it = *it;
- temp_it.object = make_number (0);
+ temp_it.object = Qnil;
memset (&temp_it.current, 0, sizeof temp_it.current);
if (what == IT_CONTINUATION)
(((temp_it.ascent + temp_it.descent)
* FONT_BASE (font)) / FONT_HEIGHT (font));
- append_stretch_glyph (&temp_it, make_number (0), stretch_width,
+ append_stretch_glyph (&temp_it, Qnil, stretch_width,
temp_it.ascent + temp_it.descent,
stretch_ascent);
}
if (it->bidi_p)
{
glyph->resolved_level = it->bidi_it.resolved_level;
- if ((it->bidi_it.type & 7) != it->bidi_it.type)
- emacs_abort ();
+ eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
glyph->bidi_type = it->bidi_it.type;
}
++it->glyph_row->used[area];
#ifdef HAVE_WINDOW_SYSTEM
/* Change the mouse cursor. */
- if (FRAME_WINDOW_P (f))
+ if (FRAME_WINDOW_P (f) && NILP (do_mouse_tracking))
{
#if ! defined (USE_GTK) && ! defined (HAVE_NS)
if (draw == DRAW_NORMAL_TEXT
while (g < e)
{
- if (((BUFFERP (g->object) || INTEGERP (g->object))
+ if (((BUFFERP (g->object) || NILP (g->object))
&& start_charpos <= g->charpos && g->charpos < end_charpos)
/* A glyph that comes from DISP_STRING is by
definition to be highlighted. */
while (g < e)
{
- if (((BUFFERP (g->object) || INTEGERP (g->object))
+ if (((BUFFERP (g->object) || NILP (g->object))
&& ((start_charpos <= g->charpos && g->charpos < end_charpos)
/* If the buffer position of the first glyph in
the row is equal to END_CHARPOS, it means
{
struct glyph *beg = prev->glyphs[TEXT_AREA];
glyph = beg + prev->used[TEXT_AREA];
- while (--glyph >= beg && INTEGERP (glyph->object));
+ while (--glyph >= beg && NILP (glyph->object));
if (glyph < beg
|| !(EQ (glyph->object, before_string)
|| EQ (glyph->object, disp_string)))
/* Skip truncation glyphs at the start of the glyph row. */
if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
for (; glyph < end
- && INTEGERP (glyph->object)
+ && NILP (glyph->object)
&& glyph->charpos < 0;
++glyph)
x += glyph->pixel_width;
or DISP_STRING, and the first glyph from buffer whose
position is between START_CHARPOS and END_CHARPOS. */
for (; glyph < end
- && !INTEGERP (glyph->object)
+ && !NILP (glyph->object)
&& !EQ (glyph->object, disp_string)
&& !(BUFFERP (glyph->object)
&& (glyph->charpos >= start_charpos
/* Skip truncation glyphs at the start of the glyph row. */
if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
for (; glyph > end
- && INTEGERP (glyph->object)
+ && NILP (glyph->object)
&& glyph->charpos < 0;
--glyph)
;
or DISP_STRING, and the first glyph from buffer whose
position is between START_CHARPOS and END_CHARPOS. */
for (; glyph > end
- && !INTEGERP (glyph->object)
+ && !NILP (glyph->object)
&& !EQ (glyph->object, disp_string)
&& !(BUFFERP (glyph->object)
&& (glyph->charpos >= start_charpos
row, and also blanks and stretch glyphs inserted by
extend_face_to_end_of_line. */
while (end > glyph
- && INTEGERP ((end - 1)->object))
+ && NILP ((end - 1)->object))
--end;
/* Scan the rest of the glyph row from the end, looking for the
first glyph that comes from BEFORE_STRING, AFTER_STRING, or
and END_CHARPOS */
for (--end;
end > glyph
- && !INTEGERP (end->object)
+ && !NILP (end->object)
&& !EQ (end->object, disp_string)
&& !(BUFFERP (end->object)
&& (end->charpos >= start_charpos
x = r2->x;
end++;
while (end < glyph
- && INTEGERP (end->object))
+ && NILP (end->object))
{
x += end->pixel_width;
++end;
and END_CHARPOS */
for ( ;
end < glyph
- && !INTEGERP (end->object)
+ && !NILP (end->object)
&& !EQ (end->object, disp_string)
&& !(BUFFERP (end->object)
&& (end->charpos >= start_charpos
if (glyph == NULL
|| area != TEXT_AREA
|| !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
- /* Glyph's OBJECT is an integer for glyphs inserted by the
+ /* Glyph's OBJECT is nil for glyphs inserted by the
display engine for its internal purposes, like truncation
and continuation glyphs and blanks beyond the end of
line's text on text terminals. If we are over such a
glyph, we are not over any text. */
- || INTEGERP (glyph->object)
+ || NILP (glyph->object)
/* R2L rows have a stretch glyph at their front, which
stands for no text, whereas L2R rows have no glyphs at
all beyond the end of text. Treat such stretch glyphs
Vmessage_stack = Qnil;
staticpro (&Vmessage_stack);
+ /* Non-nil means don't actually do any redisplay. */
DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
+
DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
message_dolog_marker1 = Fmake_marker ();
defsubr (&Scurrent_bidi_paragraph_direction);
defsubr (&Swindow_text_pixel_size);
defsubr (&Smove_point_visually);
+ defsubr (&Sbidi_find_overridden_directionality);
DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
DEFSYM (Qeval, "eval");
DEFSYM (QCdata, ":data");
+
+ /* Names of text properties relevant for redisplay. */
DEFSYM (Qdisplay, "display");
DEFSYM (Qspace_width, "space-width");
DEFSYM (Qraise, "raise");
DEFSYM (QCfile, ":file");
DEFSYM (Qfontified, "fontified");
DEFSYM (Qfontification_functions, "fontification-functions");
+
+ /* Name of the face used to highlight trailing whitespace. */
DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
+
+ /* Name and number of the face used to highlight escape glyphs. */
DEFSYM (Qescape_glyph, "escape-glyph");
+
+ /* Name and number of the face used to highlight non-breaking spaces. */
DEFSYM (Qnobreak_space, "nobreak-space");
+
+ /* The symbol 'image' which is the car of the lists used to represent
+ images in Lisp. Also a tool bar style. */
DEFSYM (Qimage, "image");
+
+ /* Tool bar styles. */
DEFSYM (Qtext, "text");
DEFSYM (Qboth, "both");
DEFSYM (Qboth_horiz, "both-horiz");
DEFSYM (Qtext_image_horiz, "text-image-horiz");
+
+ /* The image map types. */
DEFSYM (QCmap, ":map");
DEFSYM (QCpointer, ":pointer");
DEFSYM (Qrect, "rect");
DEFSYM (Qcircle, "circle");
DEFSYM (Qpoly, "poly");
+
+ /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
+ DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
+
DEFSYM (Qgrow_only, "grow-only");
- DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
DEFSYM (Qposition, "position");
DEFSYM (Qbuffer_position, "buffer-position");
DEFSYM (Qobject, "object");
+
+ /* Cursor shapes. */
DEFSYM (Qbar, "bar");
DEFSYM (Qhbar, "hbar");
DEFSYM (Qbox, "box");
DEFSYM (Qhollow, "hollow");
+
+ /* Pointer shapes. */
DEFSYM (Qhand, "hand");
DEFSYM (Qarrow, "arrow");
+ /* also Qtext */
+
DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
list_of_error = list1 (list2 (intern_c_string ("error"),
intern_c_string ("void-variable")));
staticpro (&list_of_error);
+ /* Values of those variables at last redisplay are stored as
+ properties on 'overlay-arrow-position' symbol. However, if
+ Voverlay_arrow_position is a marker, last-arrow-position is its
+ numerical position. */
DEFSYM (Qlast_arrow_position, "last-arrow-position");
DEFSYM (Qlast_arrow_string, "last-arrow-string");
+
+ /* Alternative overlay-arrow-string and overlay-arrow-bitmap
+ properties on a symbol in overlay-arrow-variable-list. */
DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
DEFSYM (Qright_to_left, "right-to-left");
DEFSYM (Qleft_to_right, "left-to-right");
+ defsubr (&Sbidi_resolved_levels);
#ifdef HAVE_WINDOW_SYSTEM
DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
doc: /* List of functions to call before redisplaying a window with scrolling.
Each function is called with two arguments, the window and its new
-display-start position. Note that these functions are also called by
-`set-window-buffer'. Also note that the value of `window-end' is not
-valid when these functions are called.
+display-start position.
+These functions are called whenever the `window-start' marker is modified,
+either to point into another buffer (e.g. via `set-window-buffer') or another
+place in the same buffer.
+Note that the value of `window-end' is not valid when these functions are
+called.
Warning: Do not use this feature to alter the way the window
is scrolled. It is not designed for that, and such use probably won't
doc: /* Non-nil means don't free realized faces. Internal use only. */);
inhibit_free_realized_faces = 0;
+ DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
+ doc: /* Non-nil means don't mirror characters even when bidi context requires that.
+Intended for use during debugging and for testing bidi display;
+see biditest.el in the test suite. */);
+ inhibit_bidi_mirroring = 0;
+
#ifdef GLYPH_DEBUG
DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
doc: /* Inhibit try_window_id display optimization. */);
hourglass_shown_p = 0;
#endif /* HAVE_WINDOW_SYSTEM */
+ /* Name of the face used to display glyphless characters. */
DEFSYM (Qglyphless_char, "glyphless-char");
+
+ /* Method symbols for Vglyphless_char_display. */
DEFSYM (Qhex_code, "hex-code");
DEFSYM (Qempty_box, "empty-box");
DEFSYM (Qthin_space, "thin-space");
or t (meaning all windows). */);
Vpre_redisplay_function = intern ("ignore");
+ /* Symbol for the purpose of Vglyphless_char_display. */
DEFSYM (Qglyphless_char_display, "glyphless-char-display");
Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));