]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Merge from origin/emacs-25
[gnu-emacs] / src / xdisp.c
index d0ff95257cefa2263a6944591779676d1253e499..d2f0d49d2b1866b6dcb86a44e4efc071a591ab9f 100644 (file)
@@ -1813,7 +1813,7 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id)
         cache and mode line face are not yet initialized.  */
       if (FRAME_FACE_CACHE (f))
        {
-         struct face *face = FACE_FROM_ID (f, face_id);
+         struct face *face = FACE_OPT_FROM_ID (f, face_id);
          if (face)
            {
              if (face->font)
@@ -2918,7 +2918,7 @@ init_iterator (struct it *it, struct window *w,
 
       /* If we have a boxed mode line, make the first character appear
         with a left box line.  */
-      face = FACE_FROM_ID (it->f, remapped_base_face_id);
+      face = FACE_OPT_FROM_ID (it->f, remapped_base_face_id);
       if (face && face->box != FACE_NO_BOX)
        it->start_of_box_run_p = true;
     }
@@ -3877,9 +3877,9 @@ handle_face_prop (struct it *it)
        {
          struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
          /* If it->face_id is -1, old_face below will be NULL, see
-            the definition of FACE_FROM_ID.  This will happen if this
+            the definition of FACE_OPT_FROM_ID.  This will happen if this
             is the initial call that gets the face.  */
-         struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
+         struct face *old_face = FACE_OPT_FROM_ID (it->f, it->face_id);
 
          /* If the value of face_id of the iterator is -1, we have to
             look in front of IT's position and see whether there is a
@@ -3888,7 +3888,7 @@ handle_face_prop (struct it *it)
            {
              int prev_face_id = face_before_it_pos (it);
 
-             old_face = FACE_FROM_ID (it->f, prev_face_id);
+             old_face = FACE_OPT_FROM_ID (it->f, prev_face_id);
            }
 
          /* If the new face has a box, but the old face does not,
@@ -3988,7 +3988,7 @@ handle_face_prop (struct it *it)
       if (new_face_id != it->face_id)
        {
          struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
-         struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
+         struct face *old_face = FACE_OPT_FROM_ID (it->f, it->face_id);
 
          /* If new face has a box but old face hasn't, this is the
             start of a run of characters with box, i.e. it has a
@@ -4847,7 +4847,6 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
          it->font_height = XCAR (XCDR (spec));
          if (!NILP (it->font_height))
            {
-             struct face *face = FACE_FROM_ID (it->f, it->face_id);
              int new_height = -1;
 
              if (CONSP (it->font_height)
@@ -4866,6 +4865,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
                {
                  /* Call function with current height as argument.
                     Value is the new height.  */
+                 struct face *face = FACE_FROM_ID (it->f, it->face_id);
                  Lisp_Object height;
                  height = safe_call1 (it->font_height,
                                       face->lface[LFACE_HEIGHT_INDEX]);
@@ -4887,6 +4887,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
                  /* Evaluate IT->font_height with `height' bound to the
                     current specified height to get the new height.  */
                  ptrdiff_t count = SPECPDL_INDEX ();
+                 struct face *face = FACE_FROM_ID (it->f, it->face_id);
 
                  specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
                  value = safe_eval (it->font_height);
@@ -6096,7 +6097,7 @@ pop_it (struct it *it)
       break;
     case GET_FROM_STRING:
       {
-       struct face *face = FACE_FROM_ID (it->f, it->face_id);
+       struct face *face = FACE_OPT_FROM_ID (it->f, it->face_id);
 
        /* Restore the face_box_p flag, since it could have been
           overwritten by the face of the object that we just finished
@@ -6777,7 +6778,7 @@ static next_element_function const get_next_element[NUM_IT_METHODS] =
    || ((IT)->cmp_it.stop_pos == (CHARPOS)                              \
        && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS,      \
                                 END_CHARPOS, (IT)->w,                  \
-                                FACE_FROM_ID ((IT)->f, (IT)->face_id), \
+                                FACE_OPT_FROM_ID ((IT)->f, (IT)->face_id),     \
                                 (IT)->string)))
 
 
@@ -7206,7 +7207,7 @@ get_next_display_element (struct it *it)
       if (it->method == GET_FROM_STRING && it->sp)
        {
          int face_id = underlying_face_id (it);
-         struct face *face = FACE_FROM_ID (it->f, face_id);
+         struct face *face = FACE_OPT_FROM_ID (it->f, face_id);
 
          if (face)
            {
@@ -7739,8 +7740,8 @@ next_element_from_display_vector (struct it *it)
       /* Glyphs in the display vector could have the box face, so we
         need to set the related flags in the iterator, as
         appropriate.  */
-      this_face = FACE_FROM_ID (it->f, it->face_id);
-      prev_face = FACE_FROM_ID (it->f, prev_face_id);
+      this_face = FACE_OPT_FROM_ID (it->f, it->face_id);
+      prev_face = FACE_OPT_FROM_ID (it->f, prev_face_id);
 
       /* Is this character the first character of a box-face run?  */
       it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
@@ -7765,7 +7766,7 @@ next_element_from_display_vector (struct it *it)
                                            it->saved_face_id);
            }
        }
-      next_face = FACE_FROM_ID (it->f, next_face_id);
+      next_face = FACE_OPT_FROM_ID (it->f, next_face_id);
       it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
                              && (!next_face
                                  || next_face->box == FACE_NO_BOX));
@@ -8809,6 +8810,8 @@ move_it_in_display_line_to (struct it *it,
                              ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
                              : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
                {
+                 bool moved_forward = false;
+
                  if (/* IT->hpos == 0 means the very first glyph
                         doesn't fit on the line, e.g. a wide image.  */
                      it->hpos == 0
@@ -8827,16 +8830,37 @@ move_it_in_display_line_to (struct it *it,
                             now that we know it fits in this row.  */
                          if (BUFFER_POS_REACHED_P ())
                            {
+                             bool can_wrap = true;
+
+                             /* If we are at a whitespace character
+                                that barely fits on this screen line,
+                                but the next character is also
+                                whitespace, we cannot wrap here.  */
+                             if (it->line_wrap == WORD_WRAP
+                                 && wrap_it.sp >= 0
+                                 && may_wrap
+                                 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+                               {
+                                 struct it tem_it;
+                                 void *tem_data = NULL;
+
+                                 SAVE_IT (tem_it, *it, tem_data);
+                                 set_iterator_to_next (it, true);
+                                 if (get_next_display_element (it)
+                                     && IT_DISPLAYING_WHITESPACE (it))
+                                   can_wrap = false;
+                                 RESTORE_IT (it, &tem_it, tem_data);
+                               }
                              if (it->line_wrap != WORD_WRAP
                                  || wrap_it.sp < 0
-                                 /* If we've just found whitespace to
-                                    wrap, effectively ignore the
-                                    previous wrap point -- it is no
-                                    longer relevant, but we won't
-                                    have an opportunity to update it,
-                                    since we've reached the edge of
-                                    this screen line.  */
-                                 || (may_wrap
+                                 /* If we've just found whitespace
+                                    where we can wrap, effectively
+                                    ignore the previous wrap point --
+                                    it is no longer relevant, but we
+                                    won't have an opportunity to
+                                    update it, since we've reached
+                                    the edge of this screen line.  */
+                                 || (may_wrap && can_wrap
                                      && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
                                {
                                  it->hpos = hpos_before_this_char;
@@ -8879,6 +8903,7 @@ move_it_in_display_line_to (struct it *it,
                                  result = MOVE_POS_MATCH_OR_ZV;
                                  break;
                                }
+                             moved_forward = true;
                              if (BUFFER_POS_REACHED_P ())
                                {
                                  if (ITERATOR_AT_END_OF_LINE_P (it))
@@ -8906,7 +8931,14 @@ move_it_in_display_line_to (struct it *it,
                     longer relevant, but we won't have an opportunity
                     to update it, since we are done with this screen
                     line.  */
-                 if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+                 if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
+                     /* If the character after the one which set the
+                        may_wrap flag is also whitespace, we can't
+                        wrap here, since the screen line cannot be
+                        wrapped in the middle of whitespace.
+                        Therefore, wrap_it _is_ relevant in that
+                        case.  */
+                     && !(moved_forward && IT_DISPLAYING_WHITESPACE (it)))
                    {
                      /* If we've found TO_X, go back there, as we now
                         know the last word fits on this screen line.  */
@@ -9087,9 +9119,18 @@ move_it_in_display_line_to (struct it *it,
 
 #undef BUFFER_POS_REACHED_P
 
-  /* If we scanned beyond to_pos and didn't find a point to wrap at,
-     restore the saved iterator.  */
-  if (atpos_it.sp >= 0)
+  /* If we scanned beyond TO_POS, restore the saved iterator either to
+     the wrap point (if found), or to atpos/atx location.  We decide which
+     data to use to restore the saved iterator state by their X coordinates,
+     since buffer positions might increase non-monotonically with screen
+     coordinates due to bidi reordering.  */
+  if (result == MOVE_LINE_CONTINUED
+      && it->line_wrap == WORD_WRAP
+      && wrap_it.sp >= 0
+      && ((atpos_it.sp >= 0 && wrap_it.current_x < atpos_it.current_x)
+         || (atx_it.sp >= 0 && wrap_it.current_x < atx_it.current_x)))
+    RESTORE_IT (it, &wrap_it, wrap_data);
+  else if (atpos_it.sp >= 0)
     RESTORE_IT (it, &atpos_it, atpos_data);
   else if (atx_it.sp >= 0)
     RESTORE_IT (it, &atx_it, atx_data);
@@ -18662,7 +18703,7 @@ try_window_id (struct window *w)
       eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
       row = find_last_row_displaying_text (w->current_matrix, &it,
                                           first_unchanged_at_end_row);
-      eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
+      eassume (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
       adjust_window_ends (w, row, true);
       eassert (w->window_end_bytepos >= 0);
       IF_DEBUG (debug_method_add (w, "A"));
@@ -18692,10 +18733,9 @@ try_window_id (struct window *w)
       struct glyph_row *current_row = current_matrix->rows + vpos;
       struct glyph_row *desired_row = desired_matrix->rows + vpos;
 
-      for (row = NULL;
-          row == NULL && vpos >= first_vpos;
-          --vpos, --current_row, --desired_row)
+      for (row = NULL; !row; --vpos, --current_row, --desired_row)
        {
+         eassert (first_vpos <= vpos);
          if (desired_row->enabled_p)
            {
              if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
@@ -18705,7 +18745,6 @@ try_window_id (struct window *w)
            row  = current_row;
        }
 
-      eassert (row != NULL);
       w->window_end_vpos = vpos + 1;
       w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
       w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
@@ -19630,15 +19669,14 @@ extend_face_to_end_of_line (struct it *it)
     return;
 
   /* The default face, possibly remapped. */
-  default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
+  default_face = FACE_OPT_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
 
   /* Face extension extends the background and box of IT->face_id
      to the end of the line.  If the background equals the background
      of the frame, we don't have to do anything.  */
-  if (it->face_before_selective_p)
-    face = FACE_FROM_ID (f, it->saved_face_id);
-  else
-    face = FACE_FROM_ID (f, it->face_id);
+  face = FACE_OPT_FROM_ID (f, (it->face_before_selective_p
+                              ? it->saved_face_id
+                              : it->face_id));
 
   if (FRAME_WINDOW_P (f)
       && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
@@ -24612,7 +24650,6 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
   face = FACE_FROM_ID (f, glyph->face_id);
 
   /* Make sure X resources of the face are allocated.  */
-  eassert (face != NULL);
   prepare_face_for_display (f, face);
 
   if (face->font)
@@ -24744,7 +24781,7 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id,
   s->cmp_id = glyph->u.cmp.id;
   s->cmp_from = glyph->slice.cmp.from;
   s->cmp_to = glyph->slice.cmp.to + 1;
-  s->face = FACE_FROM_ID (s->f, face_id);
+  s->face = FACE_OPT_FROM_ID (s->f, face_id);
   lgstring = composition_gstring_from_id (s->cmp_id);
   s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
   glyph++;
@@ -25337,7 +25374,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
   do {                                                                     \
     int face_id = (row)->glyphs[area][START].face_id;                      \
-    struct face *base_face = FACE_FROM_ID (f, face_id);                            \
+    struct face *base_face = FACE_OPT_FROM_ID (f, face_id);                \
     ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id;                \
     struct composition *cmp = composition_table[cmp_id];                   \
     XChar2b *char2b;                                                       \
@@ -25960,7 +25997,6 @@ produce_image_glyph (struct it *it)
   eassert (it->what == IT_IMAGE);
 
   face = FACE_FROM_ID (it->f, it->face_id);
-  eassert (face);
   /* Make sure X resources of the face is loaded.  */
   prepare_face_for_display (it->f, face);
 
@@ -25975,7 +26011,6 @@ produce_image_glyph (struct it *it)
     }
 
   img = IMAGE_FROM_ID (it->f, it->image_id);
-  eassert (img);
   /* Make sure X resources of the image is loaded.  */
   prepare_image_for_display (it->f, img);
 
@@ -26131,7 +26166,6 @@ produce_xwidget_glyph (struct it *it)
   eassert (it->what == IT_XWIDGET);
 
   struct face *face = FACE_FROM_ID (it->f, it->face_id);
-  eassert (face);
   /* Make sure X resources of the face is loaded.  */
   prepare_face_for_display (it->f, face);
 
@@ -27308,18 +27342,21 @@ x_produce_glyphs (struct it *it)
          int leftmost, rightmost, lowest, highest;
          int lbearing, rbearing;
          int i, width, ascent, descent;
-         int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
+         int c;
          XChar2b char2b;
          struct font_metrics *pcm;
          ptrdiff_t pos;
 
-         for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
-           if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
-             break;
+         eassume (0 < glyph_len); /* See Bug#8512.  */
+         do
+           c = COMPOSITION_GLYPH (cmp, --glyph_len);
+         while (c == '\t' && 0 < glyph_len);
+
          bool right_padded = glyph_len < cmp->glyph_len;
          for (i = 0; i < glyph_len; i++)
            {
-             if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
+             c = COMPOSITION_GLYPH (cmp, i);
+             if (c != '\t')
                break;
              cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
            }
@@ -28018,7 +28055,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
              /* Using a block cursor on large images can be very annoying.
                 So use a hollow cursor for "large" images.
                 If image is not transparent (no mask), also use hollow cursor.  */
-             struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
+             struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
              if (img != NULL && IMAGEP (img->spec))
                {
                  /* Arbitrarily, interpret "Large" as >32x32 and >NxN
@@ -30105,7 +30142,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
       /* Look for :pointer property on image.  */
       if (glyph != NULL && glyph->type == IMAGE_GLYPH)
        {
-         struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
+         struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
          if (img != NULL && IMAGEP (img->spec))
            {
              Lisp_Object image_map, hotspot;