glyph with suitably computed width. Both the blanks and the
stretch glyph are given the face of the background of the line.
This way, the terminal-specific back-end can still draw the glyphs
- left to right, even for R2L lines. */
+ left to right, even for R2L lines.
+
+ Note one important detail mentioned above: that the bidi reordering
+ engine, driven by the iterator, produces characters in R2L rows
+ starting at the character that will be the rightmost on display.
+ As far as the iterator is concerned, the geometry of such rows is
+ 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_*
+ 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.
+ This works well with most callers of move_it_*, because they need
+ to get to a specific column, and columns are still numbered in the
+ reading order, i.e. the rightmost character in a R2L paragraph is
+ still column zero. But some callers do not get well with this; a
+ notable example is mouse clicks that need to find the character
+ that corresponds to certain pixel coordinates. See
+ buffer_posn_from_coords in dispnew.c for how this is handled. */
#include <config.h>
#include <stdio.h>
#include "macros.h"
#include "disptab.h"
#include "termhooks.h"
+#include "termopts.h"
#include "intervals.h"
#include "coding.h"
#include "process.h"
#define INFINITY 10000000
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
- || defined(HAVE_NS) || defined (USE_GTK)
-extern void set_frame_menubar (struct frame *f, int, int);
-extern int pending_menu_activation;
-#endif
-
-extern int interrupt_input;
-extern int command_loop_level;
-
-extern Lisp_Object do_mouse_tracking;
-
-extern int minibuffer_auto_raise;
-extern Lisp_Object Vminibuffer_list;
-
-extern Lisp_Object Qface;
-extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
-
-extern Lisp_Object Voverriding_local_map;
-extern Lisp_Object Voverriding_local_map_menu_flag;
-extern Lisp_Object Qmenu_item;
-extern Lisp_Object Qwhen;
-extern Lisp_Object Qhelp_echo;
-extern Lisp_Object Qbefore_string, Qafter_string;
-
Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
Lisp_Object Qwindow_text_change_functions, Vwindow_text_change_functions;
/* Names of text properties relevant for redisplay. */
Lisp_Object Qdisplay;
-extern Lisp_Object Qface, Qinvisible, Qwidth;
/* Symbols used in text property values. */
Lisp_Object Qcenter;
Lisp_Object Qmargin, Qpointer;
Lisp_Object Qline_height;
-extern Lisp_Object Qheight;
-extern Lisp_Object QCwidth, QCheight, QCascent;
-extern Lisp_Object Qscroll_bar;
-extern Lisp_Object Qcursor;
/* Non-nil means highlight trailing whitespace. */
Lisp_Object Vnobreak_char_display;
#ifdef HAVE_WINDOW_SYSTEM
-extern Lisp_Object Voverflow_newline_into_fringe;
/* Test if overflow newline into fringe. Called with iterator IT
at or past right window margin, and with IT->current_x set. */
Lisp_Object Qrect, Qcircle, Qpoly;
/* Tool bar styles */
-Lisp_Object Qtext, Qboth, Qboth_horiz;
+Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
/* Non-zero means print newline to stdout before next mini-buffer
message. */
Lisp_Object help_echo_string;
Lisp_Object help_echo_window;
Lisp_Object help_echo_object;
-int help_echo_pos;
+EMACS_INT help_echo_pos;
/* Temporary variable for XTread_socket. */
static struct text_pos run_window_scroll_functions (Lisp_Object,
struct text_pos);
static void reconsider_clip_changes (struct window *, struct buffer *);
-static int text_outside_line_unchanged_p (struct window *, int, int);
+static int text_outside_line_unchanged_p (struct window *,
+ EMACS_INT, EMACS_INT);
static void store_mode_line_noprop_char (char);
static int store_mode_line_noprop (const unsigned char *, int, int);
static void x_consider_frame_title (Lisp_Object);
static int cursor_row_fully_visible_p (struct window *, int, int);
static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
-static int trailing_whitespace_p (int);
-static int message_log_check_duplicate (int, int, int, int);
+static int trailing_whitespace_p (EMACS_INT);
+static int message_log_check_duplicate (EMACS_INT, EMACS_INT,
+ EMACS_INT, EMACS_INT);
static void push_it (struct it *);
static void pop_it (struct it *);
static void sync_frame_with_window_matrix_rows (struct window *);
static int display_mode_lines (struct window *);
static int display_mode_line (struct window *, enum face_id, Lisp_Object);
static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
-static int store_mode_line_string (char *, Lisp_Object, int, int, int, Lisp_Object);
-static char *decode_mode_spec (struct window *, int, int, int,
- Lisp_Object *);
+static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
+static const char *decode_mode_spec (struct window *, int, int, int,
+ Lisp_Object *);
static void display_menu_bar (struct window *);
-static int display_count_lines (int, int, int, int, int *);
-static int display_string (unsigned char *, Lisp_Object, Lisp_Object,
+static int display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT, int,
+ EMACS_INT *);
+static int display_string (const unsigned char *, Lisp_Object, Lisp_Object,
EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
static void compute_line_metrics (struct it *);
static void run_redisplay_end_trigger_hook (struct it *);
-static int get_overlay_strings (struct it *, int);
-static int get_overlay_strings_1 (struct it *, int, int);
+static int get_overlay_strings (struct it *, EMACS_INT);
+static int get_overlay_strings_1 (struct it *, EMACS_INT, int);
static void next_overlay_string (struct it *);
static void reseat (struct it *, struct text_pos, int);
static void reseat_1 (struct it *, struct text_pos, int);
static int next_element_from_composition (struct it *);
static int next_element_from_image (struct it *);
static int next_element_from_stretch (struct it *);
-static void load_overlay_strings (struct it *, int);
+static void load_overlay_strings (struct it *, EMACS_INT);
static int init_from_display_pos (struct it *, struct window *,
struct display_pos *);
-static void reseat_to_string (struct it *, unsigned char *,
- Lisp_Object, int, int, int, int);
+static void reseat_to_string (struct it *, const unsigned char *,
+ Lisp_Object, EMACS_INT, EMACS_INT, int, int);
static enum move_it_result
move_it_in_display_line_to (struct it *, EMACS_INT, int,
enum move_operation_enum);
static void back_to_previous_line_start (struct it *);
static int forward_to_next_line_start (struct it *, int *);
static struct text_pos string_pos_nchars_ahead (struct text_pos,
- Lisp_Object, int);
-static struct text_pos string_pos (int, Lisp_Object);
-static struct text_pos c_string_pos (int, unsigned char *, int);
-static int number_of_chars (unsigned char *, int);
+ Lisp_Object, EMACS_INT);
+static struct text_pos string_pos (EMACS_INT, Lisp_Object);
+static struct text_pos c_string_pos (EMACS_INT, const unsigned char *, int);
+static EMACS_INT number_of_chars (const unsigned char *, int);
static void compute_stop_pos (struct it *);
static void compute_string_pos (struct text_pos *, struct text_pos,
Lisp_Object);
/* Return the window-relative coordinate of the right edge of display
- area AREA of window W. AREA < 0 means return the left edge of the
+ 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
/* Return the frame-relative coordinate of the right edge of display
- area AREA of window W. AREA < 0 means return the left edge of the
+ 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
box. */
INLINE void
-window_box_edges (w, area, top_left_x, top_left_y,
- bottom_right_x, bottom_right_y)
- struct window *w;
- int area;
- int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
+window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
+ int *bottom_right_x, int *bottom_right_y)
{
window_box (w, area, top_left_x, top_left_y, bottom_right_x,
bottom_right_y);
Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
int
-pos_visible_p (struct window *w, int charpos, int *x, int *y,
+pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
int *rtop, int *rbot, int *rowh, int *vpos)
{
struct it it;
in STRING, return the position NCHARS ahead (NCHARS >= 0). */
static struct text_pos
-string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, int nchars)
+string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT nchars)
{
xassert (STRINGP (string) && nchars >= 0);
if (STRING_MULTIBYTE (string))
{
- int rest = SBYTES (string) - BYTEPOS (pos);
+ EMACS_INT rest = SBYTES (string) - BYTEPOS (pos);
const unsigned char *p = SDATA (string) + BYTEPOS (pos);
int len;
for character position CHARPOS in STRING. */
static INLINE struct text_pos
-string_pos (int charpos, Lisp_Object string)
+string_pos (EMACS_INT charpos, Lisp_Object string)
{
struct text_pos pos;
xassert (STRINGP (string));
means recognize multibyte characters. */
static struct text_pos
-c_string_pos (int charpos, unsigned char *s, int multibyte_p)
+c_string_pos (EMACS_INT charpos, const unsigned char *s, int multibyte_p)
{
struct text_pos pos;
if (multibyte_p)
{
- int rest = strlen (s), len;
+ EMACS_INT rest = strlen (s);
+ int len;
SET_TEXT_POS (pos, 0, 0);
while (charpos--)
/* Value is the number of characters in C string S. MULTIBYTE_P
non-zero means recognize multibyte characters. */
-static int
-number_of_chars (unsigned char *s, int multibyte_p)
+static EMACS_INT
+number_of_chars (const unsigned char *s, int multibyte_p)
{
- int nchars;
+ EMACS_INT nchars;
if (multibyte_p)
{
- int rest = strlen (s), len;
+ EMACS_INT rest = strlen (s);
+ int len;
unsigned char *p = (unsigned char *) s;
for (nchars = 0; rest > 0; ++nchars)
&& WINDOWP (minibuf_selected_window)
&& w == XWINDOW (minibuf_selected_window))))
{
- int charpos = marker_position (current_buffer->mark);
+ EMACS_INT charpos = marker_position (current_buffer->mark);
it->region_beg_charpos = min (PT, charpos);
it->region_end_charpos = max (PT, charpos);
}
{
Lisp_Object prop, window;
int ellipses_p = 0;
- int charpos = CHARPOS (pos->pos);
+ EMACS_INT charpos = CHARPOS (pos->pos);
/* If POS specifies a position in a display vector, this might
be for an ellipsis displayed for invisible text. We won't
}
}
- composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
- it->stop_charpos, it->string);
+ if (it->cmp_it.id < 0)
+ {
+ EMACS_INT stoppos = it->end_charpos;
+
+ if (it->bidi_p && it->bidi_it.scan_dir < 0)
+ stoppos = -1;
+ composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
+ stoppos, it->string);
+ }
xassert (STRINGP (it->string)
|| (it->stop_charpos >= BEGV
}
else
{
- int base_face_id, bufpos;
+ int base_face_id;
+ EMACS_INT bufpos;
int i;
Lisp_Object from_overlay
= (it->current.overlay_string_index >= 0
if (STRINGP (it->string))
{
- int bufpos, base_face_id;
+ EMACS_INT bufpos;
+ int base_face_id;
/* No face change past the end of the string (for the case
we are padding with spaces). No face change before the
if (STRING_MULTIBYTE (it->string))
{
const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
- int rest = SBYTES (it->string) - BYTEPOS (pos);
int c, len;
struct face *face = FACE_FROM_ID (it->f, face_id);
if (STRINGP (it->string))
{
- extern Lisp_Object Qinvisible;
Lisp_Object prop, end_charpos, limit, charpos;
/* Get the value of the invisible text property at the
not have a chance to do it, if we are going to
skip any text at the beginning, which resets the
FIRST_ELT flag. */
- bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+ bidi_paragraph_init (it->paragraph_embedding,
+ &it->bidi_it, 1);
}
do
{
of buffer or string text. */
static int
-handle_single_display_spec (it, spec, object, overlay, position,
- display_replaced_before_p)
- struct it *it;
- Lisp_Object spec;
- Lisp_Object object;
- Lisp_Object overlay;
- struct text_pos *position;
- int display_replaced_before_p;
+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)
{
Lisp_Object form;
Lisp_Object location, value;
EMACS_INT
string_buffer_position (struct window *w, Lisp_Object string, EMACS_INT around_charpos)
{
- Lisp_Object limit, prop, pos;
const int MAX_DISTANCE = 1000;
EMACS_INT found = string_buffer_position_lim (w, string, around_charpos,
around_charpos + MAX_DISTANCE,
compare_overlay_entries. */
static void
-load_overlay_strings (struct it *it, int charpos)
+load_overlay_strings (struct it *it, EMACS_INT charpos)
{
- extern Lisp_Object Qwindow, Qpriority;
Lisp_Object overlay, window, str, invisible;
struct Lisp_Overlay *ov;
- int start, end;
+ EMACS_INT start, end;
int size = 20;
int n = 0, i, j, invis_p;
struct overlay_entry *entries
least one overlay string was found. */
static int
-get_overlay_strings_1 (struct it *it, int charpos, int compute_stop_p)
+get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
{
/* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
process. This fills IT->overlay_strings with strings, and sets
}
static int
-get_overlay_strings (struct it *it, int charpos)
+get_overlay_strings (struct it *it, EMACS_INT charpos)
{
it->string = Qnil;
it->method = GET_FROM_BUFFER;
of a new paragraph, next_element_from_buffer may not have a
chance to do that. */
if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
- bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+ bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
/* prev_stop can be zero, so check against BEGV as well. */
while (it->bidi_it.charpos >= BEGV
&& it->prev_stop <= it->bidi_it.charpos
short-cut. */
if (!newline_found_p)
{
- int start = IT_CHARPOS (*it);
- int limit = find_next_newline_no_quit (start, 1);
+ EMACS_INT start = IT_CHARPOS (*it);
+ EMACS_INT limit = find_next_newline_no_quit (start, 1);
Lisp_Object pos;
xassert (!STRINGP (it->string));
{
struct it it2;
- int pos;
+ EMACS_INT pos;
EMACS_INT beg, end;
Lisp_Object val, overlay;
static void
reseat (struct it *it, struct text_pos pos, int force_p)
{
- int original_pos = IT_CHARPOS (*it);
+ EMACS_INT original_pos = IT_CHARPOS (*it);
reseat_1 (it, pos, 0);
it->string_from_display_prop_p = 0;
it->face_before_selective_p = 0;
if (it->bidi_p)
- it->bidi_it.first_elt = 1;
+ {
+ it->bidi_it.first_elt = 1;
+ it->bidi_it.paragraph_dir = NEUTRAL_DIR;
+ }
if (set_stop_p)
{
calling this function. */
static void
-reseat_to_string (struct it *it, unsigned char *s, Lisp_Object string,
- int charpos, int precision, int field_width, int multibyte)
+reseat_to_string (struct it *it, const unsigned char *s, Lisp_Object string,
+ EMACS_INT charpos, EMACS_INT precision, int field_width,
+ int multibyte)
{
/* No region in strings. */
it->region_beg_charpos = it->region_end_charpos = -1;
struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
nbsp_or_shy = char_is_other;
- int decoded = it->c;
+ int c = it->c; /* This is the character to display. */
+
+ if (! it->multibyte_p && ! ASCII_CHAR_P (c))
+ {
+ xassert (SINGLE_BYTE_CHAR_P (c));
+ if (unibyte_display_via_language_environment)
+ {
+ c = DECODE_CHAR (unibyte, c);
+ if (c < 0)
+ c = BYTE8_TO_CHAR (it->c);
+ }
+ else
+ c = BYTE8_TO_CHAR (it->c);
+ }
if (it->dp
- && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
+ && (dv = DISP_CHAR_VECTOR (it->dp, c),
VECTORP (dv)))
{
struct Lisp_Vector *v = XVECTOR (dv);
goto get_next;
}
- if (unibyte_display_via_language_environment
- && !ASCII_CHAR_P (it->c))
- decoded = DECODE_CHAR (unibyte, it->c);
-
- if (it->c >= 0x80 && ! NILP (Vnobreak_char_display))
- {
- if (it->multibyte_p)
- nbsp_or_shy = (it->c == 0xA0 ? char_is_nbsp
- : it->c == 0xAD ? char_is_soft_hyphen
- : char_is_other);
- else if (unibyte_display_via_language_environment)
- nbsp_or_shy = (decoded == 0xA0 ? char_is_nbsp
- : decoded == 0xAD ? char_is_soft_hyphen
- : char_is_other);
- }
+ if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
+ nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
+ : c == 0xAD ? char_is_soft_hyphen
+ : char_is_other);
/* Translate control characters into `\003' or `^C' form.
Control characters coming from a display table entry are
the translation. This could easily be changed but I
don't believe that it is worth doing.
- If it->multibyte_p is nonzero, non-printable non-ASCII
- characters are also translated to octal form.
+ NBSP and SOFT-HYPEN are property translated too.
- If it->multibyte_p is zero, eight-bit characters that
- don't have corresponding multibyte char code are also
+ Non-printable characters and raw-byte characters are also
translated to octal form. */
- if ((it->c < ' '
+ if (((c < ' ' || c == 127) /* ASCII control chars */
? (it->area != TEXT_AREA
/* In mode line, treat \n, \t like other crl chars. */
- || (it->c != '\t'
+ || (c != '\t'
&& it->glyph_row
&& (it->glyph_row->mode_line_p || it->avoid_cursor_p))
- || (it->c != '\n' && it->c != '\t'))
+ || (c != '\n' && c != '\t'))
: (nbsp_or_shy
- || (it->multibyte_p
- ? ! CHAR_PRINTABLE_P (it->c)
- : (! unibyte_display_via_language_environment
- ? it->c >= 0x80
- : (decoded >= 0x80 && decoded < 0xA0))))))
+ || CHAR_BYTE8_P (c)
+ || ! CHAR_PRINTABLE_P (c))))
{
- /* IT->c is a control character which must be displayed
+ /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
+ or a non-printable character which must be displayed
either as '\003' or as `^C' where the '\\' and '^'
can be defined in the display table. Fill
IT->ctl_chars with glyphs for what we have to
/* Handle control characters with ^. */
- if (it->c < 128 && it->ctl_arrow_p)
+ if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
{
int g;
}
XSETINT (it->ctl_chars[0], g);
- XSETINT (it->ctl_chars[1], it->c ^ 0100);
+ XSETINT (it->ctl_chars[1], c ^ 0100);
ctl_len = 2;
goto display_control;
}
face_id = merge_faces (it->f, Qnobreak_space, 0,
it->face_id);
- it->c = ' ';
+ c = ' ';
XSETINT (it->ctl_chars[0], ' ');
ctl_len = 1;
goto display_control;
if (EQ (Vnobreak_char_display, Qt)
&& nbsp_or_shy == char_is_soft_hyphen)
{
- it->c = '-';
XSETINT (it->ctl_chars[0], '-');
ctl_len = 1;
goto display_control;
if (nbsp_or_shy)
{
XSETINT (it->ctl_chars[0], escape_glyph);
- it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
- XSETINT (it->ctl_chars[1], it->c);
+ c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
+ XSETINT (it->ctl_chars[1], c);
ctl_len = 2;
goto display_control;
}
{
- unsigned char str[MAX_MULTIBYTE_LENGTH];
- int len;
- int i;
+ char str[10];
+ int len, i;
- /* Set IT->ctl_chars[0] to the glyph for `\\'. */
- if (CHAR_BYTE8_P (it->c))
- {
- str[0] = CHAR_TO_BYTE8 (it->c);
- len = 1;
- }
- else if (it->c < 256)
- {
- str[0] = it->c;
- len = 1;
- }
- else
- {
- /* It's an invalid character, which shouldn't
- happen actually, but due to bugs it may
- happen. Let's print the char as is, there's
- not much meaningful we can do with it. */
- str[0] = it->c;
- str[1] = it->c >> 8;
- str[2] = it->c >> 16;
- str[3] = it->c >> 24;
- len = 4;
- }
+ if (CHAR_BYTE8_P (c))
+ /* Display \200 instead of \17777600. */
+ c = CHAR_TO_BYTE8 (c);
+ len = sprintf (str, "%03o", c);
+ XSETINT (it->ctl_chars[0], escape_glyph);
for (i = 0; i < len; i++)
- {
- int g;
- XSETINT (it->ctl_chars[i * 4], escape_glyph);
- /* Insert three more glyphs into IT->ctl_chars for
- the octal display of the character. */
- g = ((str[i] >> 6) & 7) + '0';
- XSETINT (it->ctl_chars[i * 4 + 1], g);
- g = ((str[i] >> 3) & 7) + '0';
- XSETINT (it->ctl_chars[i * 4 + 2], g);
- g = (str[i] & 7) + '0';
- XSETINT (it->ctl_chars[i * 4 + 3], g);
- }
- ctl_len = len * 4;
+ XSETINT (it->ctl_chars[i + 1], str[i]);
+ ctl_len = len + 1;
}
display_control:
it->ellipsis_p = 0;
goto get_next;
}
+ it->char_to_display = c;
+ }
+ else if (success_p)
+ {
+ it->char_to_display = it->c;
}
}
}
else
{
- int pos = (it->s ? -1
- : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
- : IT_CHARPOS (*it));
+ EMACS_INT pos = (it->s ? -1
+ : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
+ : IT_CHARPOS (*it));
- it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
+ it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
+ it->string);
}
}
#endif
it->cmp_it.id = -1;
composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
IT_BYTEPOS (*it),
- it->stop_charpos, Qnil);
+ it->end_charpos, Qnil);
}
}
else if (! it->cmp_it.reversed_p)
{
/* No more grapheme clusters in this composition.
Find the next stop position. */
- EMACS_INT stop = it->stop_charpos;
+ EMACS_INT stop = it->end_charpos;
if (it->bidi_it.scan_dir < 0)
/* Now we are scanning backward and don't know
where to stop. */
{
/* No more grapheme clusters in this composition.
Find the next stop position. */
- EMACS_INT stop = it->stop_charpos;
+ EMACS_INT stop = it->end_charpos;
if (it->bidi_it.scan_dir < 0)
/* Now we are scanning backward and don't know
where to stop. */
/* If this is a new paragraph, determine its base
direction (a.k.a. its base embedding level). */
if (it->bidi_it.new_paragraph)
- bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+ bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
bidi_move_to_visually_next (&it->bidi_it);
IT_BYTEPOS (*it) = it->bidi_it.bytepos;
IT_CHARPOS (*it) = it->bidi_it.charpos;
{
/* As the scan direction was changed, we must
re-compute the stop position for composition. */
- EMACS_INT stop = it->stop_charpos;
+ EMACS_INT stop = it->end_charpos;
if (it->bidi_it.scan_dir < 0)
stop = -1;
composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
composition_compute_stop_pos (&it->cmp_it,
IT_STRING_CHARPOS (*it),
IT_STRING_BYTEPOS (*it),
- it->stop_charpos, it->string);
+ it->end_charpos, it->string);
}
}
else
}
else if (STRING_MULTIBYTE (it->string))
{
- int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
const unsigned char *s = (SDATA (it->string)
+ IT_STRING_BYTEPOS (*it));
it->c = string_char_and_length (s, &it->len);
}
else if (STRING_MULTIBYTE (it->string))
{
- int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
const unsigned char *s = (SDATA (it->string)
+ IT_STRING_BYTEPOS (*it));
it->c = string_char_and_length (s, &it->len);
BYTEPOS (it->position) = CHARPOS (it->position) = -1;
}
else if (it->multibyte_p)
- {
- /* Implementation note: The calls to strlen apparently aren't a
- performance problem because there is no noticeable performance
- difference between Emacs running in unibyte or multibyte mode. */
- int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
- it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
- }
+ it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
else
it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
{
/* If we are at the beginning of a line, we can produce the
next element right away. */
- bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+ bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
bidi_move_to_visually_next (&it->bidi_it);
}
else
{
- int orig_bytepos = IT_BYTEPOS (*it);
+ EMACS_INT orig_bytepos = IT_BYTEPOS (*it);
/* We need to prime the bidi iterator starting at the line's
beginning, before we will be able to produce the next
IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
it->bidi_it.charpos = IT_CHARPOS (*it);
it->bidi_it.bytepos = IT_BYTEPOS (*it);
- bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+ bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
do
{
/* Now return to buffer position where we were asked to
IT_BYTEPOS (*it) = it->bidi_it.bytepos;
SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
{
- EMACS_INT stop = it->stop_charpos;
+ EMACS_INT stop = it->end_charpos;
if (it->bidi_it.scan_dir < 0)
stop = -1;
composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
if (it->bidi_p)
{
if (it->bidi_it.new_paragraph)
- bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+ bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
/* Resync the bidi iterator with IT's new position.
FIXME: this doesn't support bidirectional text. */
while (it->bidi_it.charpos < IT_CHARPOS (*it))
TO_CHARPOS. */
void
-move_it_to (struct it *it, int to_charpos, int to_x, int to_y, int to_vpos, int op)
+move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
{
enum move_it_result skip, skip2 = MOVE_X_REACHED;
int line_height, line_start_x = 0, reached = 0;
{
int nlines, h;
struct it it2, it3;
- int start_pos;
+ EMACS_INT start_pos;
move_further_back:
xassert (dy >= 0);
void
move_it_by_lines (struct it *it, int dvpos, int need_y_p)
{
- struct position pos;
/* The commented-out optimization uses vmotion on terminals. This
gives bad results, because elements like it->what, on which
callers such as pos_visible_p rely, aren't updated. */
- /* if (!FRAME_WINDOW_P (it->f))
+ /* struct position pos;
+ if (!FRAME_WINDOW_P (it->f))
{
struct text_pos textpos;
else
{
struct it it2;
- int start_charpos, i;
+ EMACS_INT start_charpos, i;
/* Start at the beginning of the screen line containing IT's
position. This may actually move vertically backwards,
to *Messages*. */
void
-add_to_log (char *format, Lisp_Object arg1, Lisp_Object arg2)
+add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
{
Lisp_Object args[3];
Lisp_Object msg, fmt;
char *buffer;
- int len;
+ EMACS_INT len;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
USE_SAFE_ALLOCA;
so the buffer M must NOT point to a Lisp string. */
void
-message_dolog (const char *m, int nbytes, int nlflag, int multibyte)
+message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
{
if (!NILP (Vmemory_full))
return;
struct buffer *oldbuf;
Lisp_Object oldpoint, oldbegv, oldzv;
int old_windows_or_buffers_changed = windows_or_buffers_changed;
- int point_at_end = 0;
- int zv_at_end = 0;
+ EMACS_INT point_at_end = 0;
+ EMACS_INT zv_at_end = 0;
Lisp_Object old_deactivate_mark, tem;
struct gcpro gcpro1;
if (multibyte
&& NILP (current_buffer->enable_multibyte_characters))
{
- int i, c, char_bytes;
+ EMACS_INT i;
+ int c, char_bytes;
unsigned char work[1];
/* Convert a multibyte string to single-byte
else if (! multibyte
&& ! NILP (current_buffer->enable_multibyte_characters))
{
- int i, c, char_bytes;
+ EMACS_INT i;
+ int c, char_bytes;
unsigned char *msg = (unsigned char *) m;
unsigned char str[MAX_MULTIBYTE_LENGTH];
/* Convert a single-byte string to multibyte
if (nlflag)
{
- int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
+ EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
+ int dup;
insert_1 ("\n", 1, 1, 0, 0);
scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
value N > 1 if we should also append " [N times]". */
static int
-message_log_check_duplicate (int prev_bol, int prev_bol_byte,
- int this_bol, int this_bol_byte)
+message_log_check_duplicate (EMACS_INT prev_bol, EMACS_INT prev_bol_byte,
+ EMACS_INT this_bol, EMACS_INT this_bol_byte)
{
- int i;
- int len = Z_BYTE - 1 - this_bol_byte;
+ EMACS_INT i;
+ EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
int seen_dots = 0;
unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
This may GC, so the buffer M must NOT point to a Lisp string. */
void
-message2 (const char *m, int nbytes, int multibyte)
+message2 (const char *m, EMACS_INT nbytes, int multibyte)
{
/* First flush out any partial line written with print. */
message_log_maybe_newline ();
/* The non-logging counterpart of message2. */
void
-message2_nolog (const char *m, int nbytes, int multibyte)
+message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
{
struct frame *sf = SELECTED_FRAME ();
message_enable_multibyte = multibyte;
This function cancels echoing. */
void
-message3 (Lisp_Object m, int nbytes, int multibyte)
+message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
{
struct gcpro gcpro1;
and make this cancel echoing. */
void
-message3_nolog (Lisp_Object m, int nbytes, int multibyte)
+message3_nolog (Lisp_Object m, EMACS_INT nbytes, int multibyte)
{
struct frame *sf = SELECTED_FRAME ();
message_enable_multibyte = multibyte;
that was alloca'd. */
void
-message1 (char *m)
+message1 (const char *m)
{
message2 (m, (m ? strlen (m) : 0), 0);
}
/* The non-logging counterpart of message1. */
void
-message1_nolog (char *m)
+message1_nolog (const char *m)
{
message2_nolog (m, (m ? strlen (m) : 0), 0);
}
which gets replaced with STRING. */
void
-message_with_string (char *m, Lisp_Object string, int log)
+message_with_string (const char *m, Lisp_Object string, int log)
{
CHECK_STRING (string);
/* Dump an informative message to the minibuf. If M is 0, clear out
any existing message, and let the mini-buffer text show through. */
-/* VARARGS 1 */
-void
-message (char *m, EMACS_INT a1, EMACS_INT a2, EMACS_INT a3)
+static void
+vmessage (const char *m, va_list ap)
{
if (noninteractive)
{
if (noninteractive_need_newline)
putc ('\n', stderr);
noninteractive_need_newline = 0;
- fprintf (stderr, m, a1, a2, a3);
+ vfprintf (stderr, m, ap);
if (cursor_in_echo_area == 0)
fprintf (stderr, "\n");
fflush (stderr);
{
if (m)
{
- int len;
- char *a[3];
- a[0] = (char *) a1;
- a[1] = (char *) a2;
- a[2] = (char *) a3;
+ EMACS_INT len;
len = doprnt (FRAME_MESSAGE_BUF (f),
- FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
+ FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
message2 (FRAME_MESSAGE_BUF (f), len, 0);
}
}
}
+void
+message (const char *m, ...)
+{
+ va_list ap;
+ va_start (ap, m);
+ vmessage (m, ap);
+ va_end (ap);
+}
+
/* The non-logging version of message. */
void
-message_nolog (char *m, EMACS_INT a1, EMACS_INT a2, EMACS_INT a3)
+message_nolog (const char *m, ...)
{
Lisp_Object old_log_max;
+ va_list ap;
+ va_start (ap, m);
old_log_max = Vmessage_log_max;
Vmessage_log_max = Qnil;
- message (m, a1, a2, a3);
+ vmessage (m, ap);
Vmessage_log_max = old_log_max;
+ va_end (ap);
}
time we display it---but don't redisplay it now. */
void
-truncate_echo_area (int nchars)
+truncate_echo_area (EMACS_INT nchars)
{
if (nchars == 0)
echo_area_buffer[0] = Qnil;
*/
void
-set_message (const char *s, Lisp_Object string, int nbytes, int multibyte_p)
+set_message (const char *s, Lisp_Object string,
+ EMACS_INT nbytes, int multibyte_p)
{
message_enable_multibyte
= ((s && multibyte_p)
if (STRINGP (string))
{
- int nchars;
+ EMACS_INT nchars;
if (nbytes == 0)
nbytes = SBYTES (string);
if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
{
/* Convert from multi-byte to single-byte. */
- int i, c, n;
+ EMACS_INT i;
+ int c, n;
unsigned char work[1];
/* Convert a multibyte string to single-byte. */
&& !NILP (current_buffer->enable_multibyte_characters))
{
/* Convert from single-byte to multi-byte. */
- int i, c, n;
+ EMACS_INT i;
+ int c, n;
const unsigned char *msg = (const unsigned char *) s;
unsigned char str[MAX_MULTIBYTE_LENGTH];
store_mode_line_noprop (const unsigned char *str, int field_width, int precision)
{
int n = 0;
- int dummy, nbytes;
+ EMACS_INT dummy, nbytes;
/* Copy at most PRECISION chars from STR. */
nbytes = strlen (str);
update_tool_bar (sf, 1);
#endif
}
-
- /* Motif needs this. See comment in xmenu.c. Turn it off when
- pending_menu_activation is not defined. */
-#ifdef USE_X_TOOLKIT
- pending_menu_activation = 0;
-#endif
}
int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
int hmargin, vmargin, relief, idx, end;
- extern Lisp_Object QCrelief, QCmargin, QCconversion;
/* If image is a vector, choose the image according to the
button state. */
if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
nlines != WINDOW_TOTAL_LINES (w)))
{
- extern Lisp_Object Qtool_bar_lines;
Lisp_Object frame;
int old_height = WINDOW_TOTAL_LINES (w);
frame parameter. */
if (change_height_p)
{
- extern Lisp_Object Qtool_bar_lines;
Lisp_Object frame;
int old_height = WINDOW_TOTAL_LINES (w);
int nrows;
enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
int mouse_down_p, rc;
- /* Function note_mouse_highlight is called with negative x(y
+ /* Function note_mouse_highlight is called with negative X/Y
values when mouse moves outside of the frame. */
if (x <= 0 || y <= 0)
{
struct it it;
int hscroll;
struct buffer *saved_current_buffer;
- int pt;
+ EMACS_INT pt;
int wanted_x;
/* Find point in a display of infinite width. */
/* Delta in characters and bytes for try_window_id. */
-int debug_delta, debug_delta_bytes;
+EMACS_INT debug_delta, debug_delta_bytes;
/* Values of window_end_pos and window_end_vpos at the end of
try_window_id. */
redisplay_internal for display optimization. */
static INLINE int
-text_outside_line_unchanged_p (struct window *w, int start, int end)
+text_outside_line_unchanged_p (struct window *w,
+ EMACS_INT start, EMACS_INT end)
{
int unchanged_p = 1;
&& (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
{
if (FRAME_WINDOW_P (it->f)
+ /* FIXME: if ROW->reversed_p is set, this should test
+ the right fringe, not the left one. */
&& WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
{
#ifdef HAVE_WINDOW_SYSTEM
position. BUF and PT are the current point buffer and position. */
int
-check_point_in_composition (struct buffer *prev_buf, int prev_pt,
- struct buffer *buf, int pt)
+check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
+ struct buffer *buf, EMACS_INT pt)
{
EMACS_INT start, end;
Lisp_Object prop;
if (!b->clip_changed
&& BUFFERP (w->buffer) && !NILP (w->window_end_valid))
{
- int pt;
+ EMACS_INT pt;
if (w == XWINDOW (selected_window))
pt = BUF_PT (current_buffer);
{
struct glyph_row *row
= MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
- int delta, delta_bytes;
+ EMACS_INT delta, delta_bytes;
/* We used to distinguish between two cases here,
conditioned by Z - CHARPOS (tlendpos) == ZV, for
int
set_cursor_from_row (struct window *w, struct glyph_row *row,
- struct glyph_matrix *matrix, int delta, int delta_bytes,
+ struct glyph_matrix *matrix,
+ EMACS_INT delta, EMACS_INT delta_bytes,
int dy, int dvpos)
{
struct glyph *glyph = row->glyphs[TEXT_AREA];
struct glyph *end = glyph + row->used[TEXT_AREA];
struct glyph *cursor = NULL;
/* The last known character position in row. */
- int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
+ EMACS_INT last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
int x = row->x;
EMACS_INT pt_old = PT - delta;
EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
/* Non-zero means we've seen at least one glyph that came from a
display string. */
int string_seen = 0;
- /* Largest buffer position seen so far during scan of glyph row. */
- EMACS_INT bpos_max = last_pos;
+ /* Largest and smalles buffer positions seen so far during scan of
+ glyph row. */
+ EMACS_INT bpos_max = pos_before;
+ EMACS_INT bpos_min = pos_after;
/* Last buffer position covered by an overlay string with an integer
`cursor' property. */
EMACS_INT bpos_covered = 0;
if (glyph->charpos > bpos_max)
bpos_max = glyph->charpos;
+ if (glyph->charpos < bpos_min)
+ bpos_min = glyph->charpos;
if (!glyph->avoid_cursor_p)
{
/* If we hit point, we've found the glyph on which to
else if (STRINGP (glyph->object))
{
Lisp_Object chprop;
- int glyph_pos = glyph->charpos;
+ EMACS_INT glyph_pos = glyph->charpos;
chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
glyph->object);
if (glyph->charpos > bpos_max)
bpos_max = glyph->charpos;
+ if (glyph->charpos < bpos_min)
+ bpos_min = glyph->charpos;
if (!glyph->avoid_cursor_p)
{
if (dpos == 0)
else if (STRINGP (glyph->object))
{
Lisp_Object chprop;
- int glyph_pos = glyph->charpos;
+ EMACS_INT glyph_pos = glyph->charpos;
chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
glyph->object);
}
}
else if (match_with_avoid_cursor
- /* zero-width characters produce no glyphs */
+ /* A truncated row may not include PT among its
+ character positions. Setting the cursor inside the
+ scroll margin will trigger recalculation of hscroll
+ in hscroll_window_tree. */
+ || (row->truncated_on_left_p && pt_old < bpos_min)
+ || (row->truncated_on_right_p && pt_old > bpos_max)
+ /* Zero-width characters produce no glyphs. */
|| ((row->reversed_p
? glyph_after > glyphs_end
: glyph_after < glyphs_end)
be a character in the string with the
`cursor' property, which means display
cursor on that character's glyph. */
- int strpos = glyph->charpos;
+ EMACS_INT strpos = glyph->charpos;
cursor = glyph;
for (glyph += incr;
glyph += incr)
{
Lisp_Object cprop;
- int gpos = glyph->charpos;
+ EMACS_INT gpos = glyph->charpos;
cprop = Fget_char_property (make_number (gpos),
Qcursor,
};
static int
-try_scrolling (window, just_this_one_p, scroll_conservatively,
- scroll_step, temp_scroll_step, last_line_misfit)
- Lisp_Object window;
- int just_this_one_p;
- EMACS_INT scroll_conservatively, scroll_step;
- int temp_scroll_step;
- int last_line_misfit;
+try_scrolling (Lisp_Object window, int just_this_one_p,
+ EMACS_INT scroll_conservatively, EMACS_INT scroll_step,
+ int temp_scroll_step, int last_line_misfit)
{
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
void
set_vertical_scroll_bar (struct window *w)
{
- int start, end, whole;
+ EMACS_INT start, end, whole;
/* Calculate the start and end positions for the current window.
At some point, it would be nice to choose between scrollbars
int rc;
int centering_position = -1;
int last_line_misfit = 0;
- int beg_unchanged, end_unchanged;
+ EMACS_INT beg_unchanged, end_unchanged;
SET_TEXT_POS (lpoint, PT, PT_BYTE);
opoint = lpoint;
window, set up appropriate value. */
if (!EQ (window, selected_window))
{
- int new_pt = XMARKER (w->pointm)->charpos;
- int new_pt_byte = marker_byte_position (w->pointm);
+ EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
+ EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
if (new_pt < BEGV)
{
new_pt = BEGV;
if (redisplay_tool_bar_p && redisplay_tool_bar (f))
{
- extern int ignore_mouse_drag_p;
ignore_mouse_drag_p = 1;
}
}
static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
- int *, int *);
+ EMACS_INT *, EMACS_INT *);
static struct glyph_row *
find_last_row_displaying_text (struct glyph_matrix *, struct it *,
struct glyph_row *);
static struct glyph_row *
find_last_unchanged_at_beg_row (struct window *w)
{
- int first_changed_pos = BEG + BEG_UNCHANGED;
+ EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
struct glyph_row *row;
struct glyph_row *row_found = NULL;
int yb = window_text_bottom_y (w);
changes. */
static struct glyph_row *
-find_first_unchanged_at_end_row (struct window *w, int *delta, int *delta_bytes)
+find_first_unchanged_at_end_row (struct window *w,
+ EMACS_INT *delta, EMACS_INT *delta_bytes)
{
struct glyph_row *row;
struct glyph_row *row_found = NULL;
corresponds to window_end_pos. This allows us to translate
buffer positions in the current matrix to current buffer
positions for characters not in changed text. */
- int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
- int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
- int last_unchanged_pos, last_unchanged_pos_old;
+ EMACS_INT Z_old =
+ MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
+ EMACS_INT Z_BYTE_old =
+ MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
+ EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
struct glyph_row *first_text_row
= MATRIX_FIRST_TEXT_ROW (w->current_matrix);
containing CHARPOS or null. */
struct glyph_row *
-row_containing_pos (struct window *w, int charpos, struct glyph_row *start,
- struct glyph_row *end, int dy)
+row_containing_pos (struct window *w, EMACS_INT charpos,
+ struct glyph_row *start, struct glyph_row *end, int dy)
{
struct glyph_row *row = start;
struct glyph_row *best_row = NULL;
struct glyph_row *bottom_row;
int bottom_vpos;
struct it it;
- int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
+ EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
+ int dvpos, dy;
struct text_pos start_pos;
struct run run;
int first_unchanged_at_end_vpos = 0;
struct glyph_row *last_text_row, *last_text_row_at_end;
struct text_pos start;
- int first_changed_charpos, last_changed_charpos;
+ EMACS_INT first_changed_charpos, last_changed_charpos;
#if GLYPH_DEBUG
if (inhibit_try_window_id)
|| (last_changed_charpos < CHARPOS (start) - 1
&& FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
{
- int Z_old, delta, Z_BYTE_old, delta_bytes;
+ EMACS_INT Z_old, delta, Z_BYTE_old, delta_bytes;
struct glyph_row *r0;
/* Compute how many chars/bytes have been added to or removed
if (glyph->u.cmp.automatic)
fprintf (stderr,
"[%d-%d]",
- glyph->u.cmp.from, glyph->u.cmp.to);
+ glyph->slice.cmp.from, glyph->slice.cmp.to);
fprintf (stderr, " . %4d %1.1d%1.1d\n",
glyph->face_id,
glyph->left_box_line_p,
/* Get the next character. */
if (multibyte_p)
- it.c = string_char_and_length (p, &it.len);
+ it.c = it.char_to_display = string_char_and_length (p, &it.len);
else
- it.c = *p, it.len = 1;
+ {
+ it.c = it.char_to_display = *p, it.len = 1;
+ if (! ASCII_CHAR_P (it.c))
+ it.char_to_display = BYTE8_TO_CHAR (it.c);
+ }
p += it.len;
/* Get its face. */
ilisp = make_number (p - arrow_string);
face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
- it.face_id = compute_char_face (f, it.c, face);
+ it.face_id = compute_char_face (f, it.char_to_display, face);
/* Compute its width, get its glyphs. */
n_glyphs_before = it.glyph_row->used[TEXT_AREA];
append_space_for_newline has been called. */
enum display_element_type saved_what = it->what;
int saved_c = it->c, saved_len = it->len;
+ int saved_char_to_display = it->char_to_display;
int saved_x = it->current_x;
int saved_face_id = it->face_id;
struct text_pos saved_pos;
it->what = IT_CHARACTER;
memset (&it->position, 0, sizeof it->position);
it->object = make_number (0);
- it->c = ' ';
+ it->c = it->char_to_display = ' ';
it->len = 1;
if (default_face_p)
it->face_id = saved_face_id;
it->len = saved_len;
it->c = saved_c;
+ it->char_to_display = saved_char_to_display;
return 1;
}
}
it->what = IT_CHARACTER;
memset (&it->position, 0, sizeof it->position);
it->object = make_number (0);
- it->c = ' ';
+ it->c = it->char_to_display = ' ';
it->len = 1;
/* The last row's blank glyphs should get the default face, to
avoid painting the rest of the window with the region face,
trailing whitespace. */
static int
-trailing_whitespace_p (int charpos)
+trailing_whitespace_p (EMACS_INT charpos)
{
- int bytepos = CHAR_TO_BYTE (charpos);
+ EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
int c = 0;
while (bytepos < ZV_BYTE
row->ends_at_zv_p = 1;
/* A row that displays right-to-left text must always have
its last face extended all the way to the end of line,
- even if this row ends in ZV, because we still write to th
- screen left to right. */
+ even if this row ends in ZV, because we still write to
+ the screen left to right. */
if (row->reversed_p)
extend_face_to_end_of_line (it);
break;
row->truncated_on_left_p = 1;
}
+ /* Remember the position at which this line ends.
+
+ BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
+ cannot be before the call to find_row_edges below, since that is
+ where these positions are determined. */
+ row->end = it->current;
+ if (!it->bidi_p)
+ {
+ row->minpos = row->start.pos;
+ row->maxpos = row->end.pos;
+ }
+ else
+ {
+ /* ROW->minpos and ROW->maxpos must be the smallest and
+ `1 + the largest' buffer positions in ROW. But if ROW was
+ bidi-reordered, these two positions can be anywhere in the
+ row, so we must determine them now. */
+ find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
+ }
+
/* If the start of this line is the overlay arrow-position, then
mark this glyph row as the one containing the overlay arrow.
This is clearly a mess with variable size fonts. It would be
/* Compute pixel dimensions of this line. */
compute_line_metrics (it);
- /* Remember the position at which this line ends. */
- row->end = it->current;
- if (!it->bidi_p)
- {
- row->minpos = row->start.pos;
- row->maxpos = row->end.pos;
- }
- else
- {
- /* ROW->minpos and ROW->maxpos must be the smallest and
- `1 + the largest' buffer positions in ROW. But if ROW was
- bidi-reordered, these two positions can be anywhere in the
- row, so we must determine them now. */
- find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
- }
-
/* Record whether this row ends inside an ellipsis. */
row->ends_in_ellipsis_p
= (it->method == GET_FROM_DISPLAY_VECTOR
struct bidi_it itb;
EMACS_INT pos = BUF_PT (buf);
EMACS_INT bytepos = BUF_PT_BYTE (buf);
+ int c;
if (buf != current_buffer)
set_buffer_temp (buf);
- /* Find previous non-empty line. */
+ /* bidi_paragraph_init finds the base direction of the paragraph
+ by searching forward from paragraph start. We need the base
+ direction of the current or _previous_ paragraph, so we need
+ to make sure we are within that paragraph. To that end, find
+ the previous non-empty line. */
if (pos >= ZV && pos > BEGV)
{
pos--;
bytepos = CHAR_TO_BYTE (pos);
}
- while (FETCH_BYTE (bytepos) == '\n')
+ while ((c = FETCH_BYTE (bytepos)) == '\n'
+ || c == ' ' || c == '\t' || c == '\f')
{
if (bytepos <= BEGV_BYTE)
break;
itb.charpos = pos;
itb.bytepos = bytepos;
itb.first_elt = 1;
+ itb.separator_limit = -1;
+ itb.paragraph_dir = NEUTRAL_DIR;
- bidi_paragraph_init (NEUTRAL_DIR, &itb);
+ bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
if (buf != current_buffer)
set_buffer_temp (old);
switch (itb.paragraph_dir)
{
/* A string: output it and check for %-constructs within it. */
unsigned char c;
- int offset = 0;
+ EMACS_INT offset = 0;
if (SCHARS (elt) > 0
&& (!NILP (props) || risky))
&& (mode_line_target != MODE_LINE_DISPLAY
|| it->current_x < it->last_visible_x))
{
- int last_offset = offset;
+ EMACS_INT last_offset = offset;
/* Advance to end of string or next format specifier. */
while ((c = SREF (elt, offset++)) != '\0' && c != '%')
if (offset - 1 != last_offset)
{
- int nchars, nbytes;
+ EMACS_INT nchars, nbytes;
/* Output to end of string or up to '%'. Field width
is length of string. Don't output more than
break;
case MODE_LINE_STRING:
{
- int bytepos = last_offset;
- int charpos = string_byte_to_char (elt, bytepos);
- int endpos = (precision <= 0
- ? string_byte_to_char (elt, offset)
- : charpos + nchars);
+ EMACS_INT bytepos = last_offset;
+ EMACS_INT charpos = string_byte_to_char (elt, bytepos);
+ EMACS_INT endpos = (precision <= 0
+ ? string_byte_to_char (elt, offset)
+ : charpos + nchars);
n += store_mode_line_string (NULL,
Fsubstring (elt, make_number (charpos),
break;
case MODE_LINE_DISPLAY:
{
- int bytepos = last_offset;
- int charpos = string_byte_to_char (elt, bytepos);
+ EMACS_INT bytepos = last_offset;
+ EMACS_INT charpos = string_byte_to_char (elt, bytepos);
if (precision <= 0)
nchars = string_byte_to_char (elt, offset) - charpos;
}
else /* c == '%' */
{
- int percent_position = offset;
+ EMACS_INT percent_position = offset;
/* Get the specified minimum width. Zero means
don't pad. */
else if (c != 0)
{
int multibyte;
- int bytepos, charpos;
- unsigned char *spec;
+ EMACS_INT bytepos, charpos;
+ const unsigned char *spec;
Lisp_Object string;
bytepos = percent_position;
*/
static int
-store_mode_line_string (char *string, Lisp_Object lisp_string, int copy_string,
+store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
int field_width, int precision, Lisp_Object props)
{
- int len;
+ EMACS_INT len;
int n = 0;
if (string != NULL)
static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
-static char *
+static const char *
decode_mode_spec (struct window *w, register int c, int field_width,
int precision, Lisp_Object *string)
{
case 'i':
{
- int size = ZV - BEGV;
+ EMACS_INT size = ZV - BEGV;
pint2str (decode_mode_spec_buf, field_width, size);
return decode_mode_spec_buf;
}
case 'I':
{
- int size = ZV - BEGV;
+ EMACS_INT size = ZV - BEGV;
pint2hrstr (decode_mode_spec_buf, field_width, size);
return decode_mode_spec_buf;
}
case 'l':
{
- int startpos, startpos_byte, line, linepos, linepos_byte;
- int topline, nlines, junk, height;
+ EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
+ int topline, nlines, height;
+ EMACS_INT junk;
/* %c and %l are ignored in `frame-title-format'. */
if (mode_line_target == MODE_LINE_TITLE)
else if (nlines < height + 25 || nlines > height * 3 + 50
|| linepos == BUF_BEGV (b))
{
- int limit = BUF_BEGV (b);
- int limit_byte = BUF_BEGV_BYTE (b);
- int position;
+ EMACS_INT limit = BUF_BEGV (b);
+ EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
+ EMACS_INT position;
int distance = (height * 2 + 30) * line_number_display_limit_width;
if (startpos - distance > limit)
case 'p':
{
- int pos = marker_position (w->start);
- int total = BUF_ZV (b) - BUF_BEGV (b);
+ EMACS_INT pos = marker_position (w->start);
+ EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
{
so get us a 2-digit number that is close. */
if (total == 100)
total = 99;
- sprintf (decode_mode_spec_buf, "%2d%%", total);
+ sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
return decode_mode_spec_buf;
}
}
/* Display percentage of size above the bottom of the screen. */
case 'P':
{
- int toppos = marker_position (w->start);
- int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
- int total = BUF_ZV (b) - BUF_BEGV (b);
+ EMACS_INT toppos = marker_position (w->start);
+ EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
+ EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
if (botpos >= BUF_ZV (b))
{
if (total == 100)
total = 99;
if (toppos <= BUF_BEGV (b))
- sprintf (decode_mode_spec_buf, "Top%2d%%", total);
+ sprintf (decode_mode_spec_buf, "Top%2ld%%", (long)total);
else
- sprintf (decode_mode_spec_buf, "%2d%%", total);
+ sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
return decode_mode_spec_buf;
}
}
obj = Fget_buffer_process (Fcurrent_buffer ());
if (NILP (obj))
return "no process";
-#ifdef subprocesses
+#ifndef MSDOS
obj = Fsymbol_name (Fprocess_status (obj));
#endif
break;
Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
static int
-display_count_lines (int start, int start_byte, int limit_byte, int count,
- int *byte_pos_ptr)
+display_count_lines (EMACS_INT start, EMACS_INT start_byte,
+ EMACS_INT limit_byte, int count,
+ EMACS_INT *byte_pos_ptr)
{
register unsigned char *cursor;
unsigned char *base;
Value is the number of columns displayed. */
static int
-display_string (string, lisp_string, face_string, face_string_pos,
- start, it, field_width, precision, max_x, multibyte)
- unsigned char *string;
- Lisp_Object lisp_string;
- Lisp_Object face_string;
- EMACS_INT face_string_pos;
- EMACS_INT start;
- struct it *it;
- int field_width, precision, max_x;
- int multibyte;
+display_string (const unsigned char *string, Lisp_Object lisp_string, Lisp_Object face_string,
+ EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
+ int field_width, int precision, int max_x, int multibyte)
{
int hpos_at_start = it->hpos;
int saved_face_id = it->face_id;
if (face->font)
{
- unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
+ unsigned code;
+
+ if (CHAR_BYTE8_P (glyph->u.ch))
+ code = CHAR_TO_BYTE8 (glyph->u.ch);
+ else
+ code = face->font->driver->encode_char (face->font, glyph->u.ch);
if (code != FONT_INVALID_CODE)
STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
}
+/* 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
+get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
+{
+ unsigned code;
+
+ if (CHAR_BYTE8_P (c))
+ code = CHAR_TO_BYTE8 (c);
+ else
+ code = font->driver->encode_char (font, c);
+
+ if (code == FONT_INVALID_CODE)
+ return 0;
+ STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+ return 1;
+}
+
+
/* Fill glyph string S with composition components specified by S->cmp.
BASE_FACE is the base face of the composition.
glyph = s->row->glyphs[s->area] + start;
last = s->row->glyphs[s->area] + end;
s->cmp_id = glyph->u.cmp.id;
- s->cmp_from = glyph->u.cmp.from;
- s->cmp_to = glyph->u.cmp.to + 1;
+ s->cmp_from = glyph->slice.cmp.from;
+ s->cmp_to = glyph->slice.cmp.to + 1;
s->face = FACE_FROM_ID (s->f, face_id);
lgstring = composition_gstring_from_id (s->cmp_id);
s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
while (glyph < last
&& glyph->u.cmp.automatic
&& glyph->u.cmp.id == s->cmp_id
- && s->cmp_to == glyph->u.cmp.from)
- s->cmp_to = (glyph++)->u.cmp.to + 1;
+ && s->cmp_to == glyph->slice.cmp.from)
+ s->cmp_to = (glyph++)->slice.cmp.to + 1;
for (i = s->cmp_from; i < s->cmp_to; i++)
{
xassert (s->first_glyph->type == IMAGE_GLYPH);
s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
xassert (s->img);
- s->slice = s->first_glyph->slice;
+ s->slice = s->first_glyph->slice.img;
s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
s->font = s->face->font;
s->width = s->first_glyph->pixel_width;
Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
struct font_metrics metrics;
- composition_gstring_width (gstring, glyph->u.cmp.from,
- glyph->u.cmp.to + 1, &metrics);
+ composition_gstring_width (gstring, glyph->slice.cmp.from,
+ glyph->slice.cmp.to + 1, &metrics);
if (metrics.rbearing > metrics.width)
*right = metrics.rbearing - metrics.width;
if (metrics.lbearing < 0)
glyph->glyph_not_available_p = it->glyph_not_available_p;
glyph->face_id = it->face_id;
glyph->u.ch = it->char_to_display;
- glyph->slice = null_glyph_slice;
+ glyph->slice.img = null_glyph_slice;
glyph->font_type = FONT_TYPE_UNKNOWN;
if (it->bidi_p)
{
{
glyph->u.cmp.automatic = 0;
glyph->u.cmp.id = it->cmp_it.id;
+ glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
}
else
{
glyph->u.cmp.automatic = 1;
glyph->u.cmp.id = it->cmp_it.id;
- glyph->u.cmp.from = it->cmp_it.from;
- glyph->u.cmp.to = it->cmp_it.to - 1;
+ glyph->slice.cmp.from = it->cmp_it.from;
+ glyph->slice.cmp.to = it->cmp_it.to - 1;
}
glyph->avoid_cursor_p = it->avoid_cursor_p;
glyph->multibyte_p = it->multibyte_p;
glyph->padding_p = 0;
glyph->glyph_not_available_p = 0;
glyph->face_id = it->face_id;
- glyph->slice = null_glyph_slice;
glyph->font_type = FONT_TYPE_UNKNOWN;
if (it->bidi_p)
{
glyph->glyph_not_available_p = 0;
glyph->face_id = it->face_id;
glyph->u.img_id = img->id;
- glyph->slice = slice;
+ glyph->slice.img = slice;
glyph->font_type = FONT_TYPE_UNKNOWN;
if (it->bidi_p)
{
glyph->face_id = it->face_id;
glyph->u.stretch.ascent = ascent;
glyph->u.stretch.height = height;
- glyph->slice = null_glyph_slice;
+ glyph->slice.img = null_glyph_slice;
glyph->font_type = FONT_TYPE_UNKNOWN;
if (it->bidi_p)
{
it2 = *it;
if (it->multibyte_p)
+ it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
+ else
{
- int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
- - IT_BYTEPOS (*it));
- it2.c = STRING_CHAR_AND_LENGTH (p, it2.len);
+ it2.c = it2.char_to_display = *p, it2.len = 1;
+ if (! ASCII_CHAR_P (it2.c))
+ it2.char_to_display = BYTE8_TO_CHAR (it2.c);
}
- else
- it2.c = *p, it2.len = 1;
it2.glyph_row = NULL;
it2.what = IT_CHARACTER;
if (it->what == IT_CHARACTER)
{
XChar2b char2b;
- struct font *font;
struct face *face = FACE_FROM_ID (it->f, it->face_id);
- struct font_metrics *pcm;
- int font_not_found_p;
+ struct font *font = face->font;
+ int font_not_found_p = font == NULL;
+ struct font_metrics *pcm = NULL;
int boff; /* baseline offset */
- /* We may change it->multibyte_p upon unibyte<->multibyte
- conversion. So, save the current value now and restore it
- later.
-
- Note: It seems that we don't have to record multibyte_p in
- struct glyph because the character code itself tells whether
- or not the character is multibyte. Thus, in the future, we
- must consider eliminating the field `multibyte_p' in the
- struct glyph. */
- int saved_multibyte_p = it->multibyte_p;
-
- /* Maybe translate single-byte characters to multibyte, or the
- other way. */
- it->char_to_display = it->c;
- if (!ASCII_BYTE_P (it->c)
- && ! it->multibyte_p)
- {
- if (SINGLE_BYTE_CHAR_P (it->c)
- && unibyte_display_via_language_environment)
- {
- struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
-
- /* get_next_display_element assures that this decoding
- never fails. */
- it->char_to_display = DECODE_CHAR (unibyte, it->c);
- it->multibyte_p = 1;
- it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
- -1, Qnil);
- face = FACE_FROM_ID (it->f, it->face_id);
- }
- }
- /* Get font to use. Encode IT->char_to_display. */
- get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
- &char2b, it->multibyte_p, 0);
- font = face->font;
-
- font_not_found_p = font == NULL;
if (font_not_found_p)
{
/* When no suitable font found, display an empty box based
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
}
- if (it->char_to_display >= ' '
- && (!it->multibyte_p || it->char_to_display < 128))
+ if (it->char_to_display != '\n' && it->char_to_display != '\t')
{
- /* Either unibyte or ASCII. */
int stretched_p;
it->nglyphs = 1;
- pcm = get_per_char_metric (it->f, font, &char2b);
-
if (it->override_ascent >= 0)
{
it->ascent = it->override_ascent;
it->descent = FONT_DESCENT (font) - boff;
}
+ if (! font_not_found_p
+ && get_char_glyph_code (it->char_to_display, font, &char2b))
+ {
+ pcm = get_per_char_metric (it->f, font, &char2b);
+ if (pcm->width == 0
+ && pcm->rbearing == 0 && pcm->lbearing == 0)
+ pcm = NULL;
+ }
+
if (pcm)
{
it->phys_ascent = pcm->ascent + boff;
it->glyph_not_available_p = 1;
it->phys_ascent = it->ascent;
it->phys_descent = it->descent;
- it->pixel_width = FONT_WIDTH (font);
+ it->pixel_width = font->space_width;
}
if (it->constrain_row_ascent_descent_p)
}
}
}
- else if (it->char_to_display == '\t')
+ else /* i.e. (it->char_to_display == '\t') */
{
if (font->space_width > 0)
{
it->nglyphs = 1;
}
}
- else
- {
- /* A multi-byte character. Assume that the display width of the
- character is the width of the character multiplied by the
- width of the font. */
-
- /* If we found a font, this font should give us the right
- metrics. If we didn't find a font, use the frame's
- default font and calculate the width of the character by
- multiplying the width of font by the width of the
- character. */
-
- pcm = get_per_char_metric (it->f, font, &char2b);
-
- if (font_not_found_p || !pcm)
- {
- int char_width = CHAR_WIDTH (it->char_to_display);
-
- if (char_width == 0)
- /* This is a non spacing character. But, as we are
- going to display an empty box, the box must occupy
- at least one column. */
- char_width = 1;
- it->glyph_not_available_p = 1;
- it->pixel_width = font->space_width * char_width;
- it->phys_ascent = FONT_BASE (font) + boff;
- it->phys_descent = FONT_DESCENT (font) - boff;
- }
- else
- {
- it->pixel_width = pcm->width;
- it->phys_ascent = pcm->ascent + boff;
- it->phys_descent = pcm->descent - boff;
- if (it->glyph_row
- && (pcm->lbearing < 0
- || pcm->rbearing > pcm->width))
- it->glyph_row->contains_overlapping_glyphs_p = 1;
- }
- it->nglyphs = 1;
- it->ascent = FONT_BASE (font) + boff;
- it->descent = FONT_DESCENT (font) - boff;
- if (face->box != FACE_NO_BOX)
- {
- int thick = face->box_line_width;
-
- if (thick > 0)
- {
- it->ascent += thick;
- it->descent += thick;
- }
- else
- thick = - thick;
-
- if (it->start_of_box_run_p)
- it->pixel_width += thick;
- if (it->end_of_box_run_p)
- it->pixel_width += thick;
- }
-
- /* If face has an overline, add the height of the overline
- (1 pixel) and a 1 pixel margin to the character height. */
- if (face->overline_p)
- it->ascent += overline_margin;
-
- take_vertical_position_into_account (it);
-
- if (it->ascent < 0)
- it->ascent = 0;
- if (it->descent < 0)
- it->descent = 0;
-
- if (it->glyph_row)
- append_glyph (it);
- if (it->pixel_width == 0)
- /* We assure that all visible glyphs have at least 1-pixel
- width. */
- it->pixel_width = 1;
- }
- it->multibyte_p = saved_multibyte_p;
}
else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
{
XChar2b char2b;
struct font_metrics *pcm;
int font_not_found_p;
- int pos;
+ EMACS_INT pos;
for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
}
else
{
- width = FONT_WIDTH (font);
+ width = font->space_width;
ascent = FONT_BASE (font);
descent = FONT_DESCENT (font);
lbearing = 0;
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
Lisp_Object pointer = Qnil;
- int charpos, dx, dy, width, height;
+ int dx, dy, width, height;
+ EMACS_INT charpos;
Lisp_Object string, object = Qnil;
Lisp_Object pos, help;
Lisp_Object *overlay_vec = NULL;
int noverlays;
struct buffer *obuf;
- int obegv, ozv, same_region;
+ EMACS_INT obegv, ozv;
+ int same_region;
/* Find the glyph under X/Y. */
glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
!NILP (image_map))
&& (hotspot = find_hot_spot (image_map,
- glyph->slice.x + dx,
- glyph->slice.y + dy),
+ glyph->slice.img.x + dx,
+ glyph->slice.img.y + dy),
CONSP (hotspot))
&& (hotspot = XCDR (hotspot), CONSP (hotspot)))
{
/* If we are on a display string with no mouse-face,
check if the text under it has one. */
struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
- int start = MATRIX_ROW_START_CHARPOS (r);
+ EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
pos = string_buffer_position (w, object, start);
if (pos > 0)
{
else
{
Lisp_Object object = glyph->object;
- int charpos = glyph->charpos;
+ EMACS_INT charpos = glyph->charpos;
/* Try text properties. */
if (STRINGP (object)
see if the buffer text ``under'' it does. */
struct glyph_row *r
= MATRIX_ROW (w->current_matrix, vpos);
- int start = MATRIX_ROW_START_CHARPOS (r);
+ EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
EMACS_INT pos = string_buffer_position (w, object, start);
if (pos > 0)
{
if (NILP (pointer))
{
Lisp_Object object = glyph->object;
- int charpos = glyph->charpos;
+ EMACS_INT charpos = glyph->charpos;
/* Try text properties. */
if (STRINGP (object)
see if the buffer text ``under'' it does. */
struct glyph_row *r
= MATRIX_ROW (w->current_matrix, vpos);
- int start = MATRIX_ROW_START_CHARPOS (r);
+ EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
EMACS_INT pos = string_buffer_position (w, object,
start);
if (pos > 0)
staticpro (&Qboth);
Qboth_horiz = intern_c_string ("both-horiz");
staticpro (&Qboth_horiz);
+ Qtext_image_horiz = intern_c_string ("text-image-horiz");
+ staticpro (&Qtext_image_horiz);
QCmap = intern_c_string (":map");
staticpro (&QCmap);
QCpointer = intern_c_string (":pointer");
DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style,
doc: /* *Tool bar style to use.
It can be one of
- image - show images only
- text - show text only
- both - show both, text under image
- both-horiz - show text to the right of the image
- any other - use system default or image if no system default. */);
+ image - show images only
+ text - show text only
+ both - show both, text below image
+ both-horiz - show text to the right of the image
+ text-image-horiz - show text to the left of the image
+ any other - use system default or image if no system default. */);
Vtool_bar_style = Qnil;
DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size,