emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Obtain X / HPOS with move_it_to at eol when buffer-display-table lin


From: Keith David Bershatsky
Subject: Re: Obtain X / HPOS with move_it_to at eol when buffer-display-table line-feed
Date: Tue, 29 Aug 2017 11:51:07 -0700

Thank you, Eli, for looking at this particular thread.

I am creating pilcrows at the end of each line using the following code:

(let ((face (face-id 'font-lock-warning-face)))
  (aset (or buffer-display-table
            (setq buffer-display-table (make-display-table))) ?\n `[(182 . 
,face) ?\n]))

Using POS, I would like to obtain X/Y/HPOS/VPOS for any particular eol pilcrow. 
 If I search for POS at the end of the line using move_it_to, then it.current_x 
and it.current_hpos are not the values that I need.  In that situation, I have 
to subtract frame-char-width from it.current_x, and I have to subtract 1 from 
it.current_hpos.  it.current_x and it.current_hpos are essentially off to a 
tune of one character to the right of the pilcrow.

I would like to come up with a more sophisticated test for when IT is at the 
end of the line looking at a pilcrow as described above, and when that 
situation exists, then return the X and HPOS to the left of the pilcrow 
(instead of to the right of the pilcrow).  [I am then going to place a fake 
cursor on the pilcrow, which is beyond the scope of the current issue.]

Lisp_Object
get_x_y_hpos_vpos (struct window *w, ptrdiff_t start, ptrdiff_t position)
{
  struct it it;
  void *itdata = bidi_shelve_cache ();
  struct text_pos start_text_position;
  int x, y, hpos, vpos;
  struct frame *f = XFRAME (w->frame);
  int frame_char_width = FRAME_COLUMN_WIDTH (f);
  ptrdiff_t pt_original = PT;
  ptrdiff_t pt_byte_original = PT_BYTE;
  /* marker_position (w->start) is NOT reliable here. */
  if (position >= start)
    {
      SET_TEXT_POS_FROM_MARKER (start_text_position, w->start);
      start_display (&it, w, start_text_position);
      /* Move IT to POSINT, but no farther than the lower right-hand corner of 
the visible window. */
      move_it_to (&it, position, it.last_visible_x, it.last_visible_y - 1, -1, 
MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
      if (IT_CHARPOS (it) != position)
        goto done;
      y = it.current_y;
      if (WINDOW_HEADER_LINE_HEIGHT (w) > 0)
        vpos = it.vpos + 1;
        else
          vpos = it.vpos;
      if (FETCH_BYTE (IT_BYTEPOS (it)) == '\n'
          /* && (aref buffer-display-table ?\n) == [(182 . 127) 10] */
          )
        {
          x = it.current_x - frame_char_width;
          hpos = it.hpos - 1;
        }
        else
          {
            x = it.current_x;
            hpos = it.hpos;
          }
    }
    else
      {
        done:
        x = -1;
        y = -1;
        hpos = -1;
        vpos = -1;
      }
  bidi_unshelve_cache (itdata, false);
  return listn (CONSTYPE_HEAP, 4, make_number (x), make_number (y), make_number 
(hpos), make_number (vpos));
}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]