all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Re: Obtain X / HPOS with move_it_to at eol when buffer-display-table line-feed
@ 2017-08-31 16:07 Keith David Bershatsky
  2017-08-31 16:17 ` Eli Zaretskii
  0 siblings, 1 reply; 8+ messages in thread
From: Keith David Bershatsky @ 2017-08-31 16:07 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Thank you, Eli, for the suggestion to stop IT before it gets to the new line (which is displayed using the display-table entry).

The argument of it.last_visible_x is important for the very last line of the visible window, or else IT will not continue looking for POS until it reaches the window-end.

I am assuming by your comments that we are looking for EOL_POSITION minus 1 point, and from there I should examine the character at that location to obtain its width and then add that width to it.current_x in order to get the X of the pilcrow beginning ....

This is a work in progress and I'll keep plugging away as time permits.

Keith

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DATE:  [08-30-2017 12:03:52] <30 Aug 2017 22:03:52 +0300>
FROM:  Eli Zaretskii <eliz@gnu.org>
> 
> * * *
> 
> > With respect to eol pilcrows, move_it_to gives X and HPOS coordinates for an invisible \n to the right of the pilcrow.  We essentially have ¶\n, and IT cannot see the pilcrow.  The X and HPOS returned by move_it_to gives us ¶|\n instead of |¶\n.  Stated another way, X and HPOS are reported as being on the end of the pilcrow, instead of the beginning of the pilcrow.
> 
> But this is because you told move_it_to to move to the end of the
> screen line, by specifying it.last_visible_x - 1 as the X coordinate.
> What happens if you tell it to stop at the buffer position of the
> newline instead?
> 
> > Perhaps there is some way to help move_it_to see the pilcrow, or at least pretend that it exists?
> 
> move_it_to always stops when it delivers characters from the buffer,
> so if there are display or overlay strings, or glyphs come from a
> display table, it will go on until those are exhausted, and it is back
> at the next character from buffer text.  So you should try stopping it
> before it gets to the newline, which is displayed using the
> display-table entry.



^ permalink raw reply	[flat|nested] 8+ messages in thread
* Re: Obtain X / HPOS with move_it_to at eol when buffer-display-table line-feed
@ 2017-08-30 18:35 Keith David Bershatsky
  2017-08-30 19:03 ` Eli Zaretskii
  0 siblings, 1 reply; 8+ messages in thread
From: Keith David Bershatsky @ 2017-08-30 18:35 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Fake cursors are created/erased by hijacking w->phys_cursor.x/y/hpos/vpos and calling either erase_phys_cursor or draw_window_cursor.  The creation of a glyph/character on top of the cursor is optional so that a floating cursor anywhere is possible if so desired.

With respect to eol pilcrows, move_it_to gives X and HPOS coordinates for an invisible \n to the right of the pilcrow.  We essentially have ¶\n, and IT cannot see the pilcrow.  The X and HPOS returned by move_it_to gives us ¶|\n instead of |¶\n.  Stated another way, X and HPOS are reported as being on the end of the pilcrow, instead of the beginning of the pilcrow.

My preference would be to continue using the built-in method for drawing/erasing cursors -- i.e., let erase_phys_cursor and draw_window_cursor do all the work for us, and we only need to give them precise coordinates (x/y/hpos/vpos).

Perhaps there is some way to help move_it_to see the pilcrow, or at least pretend that it exists?

  /* EXAMPLES of (aref buffer-display-table ?\n):  [(182 . 127) 10]; [182 10]; [10] */
  Lisp_Object buffer_display_table = BVAR (b, display_table);
  bool buffer_display_table_p = !NILP (buffer_display_table);
  Lisp_Object line_feed_vector;
  if (buffer_display_table_p)
    line_feed_vector = Faref (buffer_display_table, make_number (10));
  /* Reset it.current_x and it.hpos to the desired locations. */
  if (FETCH_BYTE (IT_BYTEPOS (it)) == '\n'
      && buffer_display_table_p
      && VECTORP (line_feed_vector)
      && ASIZE (line_feed_vector) > 1)
   {
     it.current_x = ABRACADABRA_X;
     it.hpos = ABRACADABRA_HPOS;
   }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DATE:  [08-30-2017 09:51:56] <30 Aug 2017 19:51:56 +0300>
FROM:  Eli Zaretskii <eliz@gnu.org>
> 
> * * *
> 
> When you say "X POS for any particular eol pilcrow", do you mean the x
> coordinate of the beginning of the pilcrow or of its end?
> 
> And what do you get instead when you use move_it_to like you show?
> 
> Also, why do you care about the exact coordinate of the pilcrow?  You
> could simply reach it and then do there whatever you want, no matter
> what is the coordinate.
> 
> * * *



^ permalink raw reply	[flat|nested] 8+ messages in thread
* Re: Obtain X / HPOS with move_it_to at eol when buffer-display-table line-feed
@ 2017-08-29 18:51 Keith David Bershatsky
  2017-08-30 16:51 ` Eli Zaretskii
  0 siblings, 1 reply; 8+ messages in thread
From: Keith David Bershatsky @ 2017-08-29 18:51 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

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));
}



^ permalink raw reply	[flat|nested] 8+ messages in thread
* Obtain X / HPOS with move_it_to at eol when buffer-display-table line-feed
@ 2017-08-29  7:01 Keith David Bershatsky
  2017-08-29 14:59 ` Eli Zaretskii
  0 siblings, 1 reply; 8+ messages in thread
From: Keith David Bershatsky @ 2017-08-29  7:01 UTC (permalink / raw)
  To: Emacs Devel

I am working on my own feature requests 17684 (thin vertical line) and 22873 (multiple fake cursors).

I am having difficulty calculating the X and HPOS using move_it_to when a buffer-display-table contains an entry for a line feed (aka \n).  I am looking for a more eloquent way of of handling this instead of subtracting the frame-char-width from it.current.pos, and also subtracting 1 from it.current.hpos.  We can test the buffer-display-table with something like (aref buffer-display-table ?\n), which in my use-case yields [(182 . 127) 10] because I also use face to color the eol character.

We test for a line feed with:  FETCH_BYTE (IT_BYTEPOS (it)) == '\n'

We move to POS using:

move_it_to (&it, POS, it.last_visible_x, it.last_visible_y - 1, -1, MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);

Is there a better way to handle this instead of subtracting frame-char-width from X and subtracting 1 from HPOS?

Thanks,

Keith



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-08-31 16:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-31 16:07 Obtain X / HPOS with move_it_to at eol when buffer-display-table line-feed Keith David Bershatsky
2017-08-31 16:17 ` Eli Zaretskii
  -- strict thread matches above, loose matches on Subject: below --
2017-08-30 18:35 Keith David Bershatsky
2017-08-30 19:03 ` Eli Zaretskii
2017-08-29 18:51 Keith David Bershatsky
2017-08-30 16:51 ` Eli Zaretskii
2017-08-29  7:01 Keith David Bershatsky
2017-08-29 14:59 ` Eli Zaretskii

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.