unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Drawing dirty rectangles with expose_window:  row->clip = fr
@ 2019-04-02  1:55 Keith David Bershatsky
  2019-04-02 14:48 ` Eli Zaretskii
  2019-04-02 19:34 ` Alan Third
  0 siblings, 2 replies; 8+ messages in thread
From: Keith David Bershatsky @ 2019-04-02  1:55 UTC (permalink / raw)
  To: Emacs Devel

I am working on feature requests #22873 (multiple fake cursors) and #17684 (crosshairs that track the cursor position).

Even though ns_clip_to_rect returns TRUE, "row->clip = fr;" in expose_window can sometimes prevent glyphs from being drawn within the rectangle that is passed as an argument of ns_clip_to_rect.  This has the effect of permitting fake cursors to be drawn, but then glyphs cannot be drawn on top of hollow/box fake cursors.

How can I reconcile a false_positive with ns_clip_to_rect?

Or, perhaps "row->clip = fr;" in expose_window needs to be adjusted to permit the drawing of glyphs?

If I comment out "row->clip = fr;" in expose_window, the problem goes away.

Keith



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

* Re: Drawing dirty rectangles with expose_window:  row->clip = fr
  2019-04-02  1:55 Drawing dirty rectangles with expose_window: row->clip = fr Keith David Bershatsky
@ 2019-04-02 14:48 ` Eli Zaretskii
  2019-04-02 19:34 ` Alan Third
  1 sibling, 0 replies; 8+ messages in thread
From: Eli Zaretskii @ 2019-04-02 14:48 UTC (permalink / raw)
  To: Keith David Bershatsky; +Cc: emacs-devel

> Date: Mon, 01 Apr 2019 18:55:46 -0700
> From: Keith David Bershatsky <esq@lawlist.com>
> 
> Even though ns_clip_to_rect returns TRUE, "row->clip = fr;" in expose_window can sometimes prevent glyphs from being drawn within the rectangle that is passed as an argument of ns_clip_to_rect.  This has the effect of permitting fake cursors to be drawn, but then glyphs cannot be drawn on top of hollow/box fake cursors.
> 
> How can I reconcile a false_positive with ns_clip_to_rect?

Is the fake cursor entirely inside the rectangle described by 'fr', or
is it or some of its parts outside?

> Or, perhaps "row->clip = fr;" in expose_window needs to be adjusted to permit the drawing of glyphs?

It already is, AFAIU.  Barring bugs, that is.



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

* Re: Drawing dirty rectangles with expose_window:  row->clip = fr
@ 2019-04-02 16:27 Keith David Bershatsky
  2019-04-02 16:51 ` Eli Zaretskii
  0 siblings, 1 reply; 8+ messages in thread
From: Keith David Bershatsky @ 2019-04-02 16:27 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Thank you, Eli, for reviewing/responding to this particular thread.

In this example, there is one frame with two windows in a top/bottom equal split.  The top window (*scratch*) does not have any fake cursors.  The bottom window (*MC-TEST*) does have fake cursors.  It appears that expose_window is drawing the mode-line of the top window, and the rectangle extends down into the first line of the bottom window that has fake cursors.  The fake cursors draw on the first line of the bottom window, but the glyphs do not draw on top of the box/hollow cursors.  This happens at the section of expose_window where it has the comment: 

/* Display the mode line if there is one.  */

B.  expose_window (#<window 3 on *scratch*>):  vpos (3)
    fr->x (0) | fr->y (258) | fr->width (595) | fr->height (16)
    r.x (0) | r.y (256) | r.width (591) | r.height (16)

mc_ns_draw_window_cursor (#<window 6 on *MC-TEST*>):
  x (42) | fx (52) | y (0) | fy (274) | hpos (6) | vpos (0)
  wd (7) | h (16) | RGB (1.000000/0.000000/0.270588)
  cursor_type (FRAMED_BOX_CURSOR) | glyph_flavor (MC_GLYPH)

mc_ns_draw_window_cursor (#<window 6 on *MC-TEST*>):
  x (35) | fx (45) | y (0) | fy (274) | hpos (5) | vpos (0)
  wd (3) | h (16) | RGB (0.000000/1.000000/1.000000)
  cursor_type (BAR_CURSOR) | glyph_flavor (MC_GLYPH)


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

> Date: [04-02-2019 07:48:11] <02 Apr 2019 17:48:11 +0300>
> From: Eli Zaretskii <eliz@gnu.org>
> To: Keith David Bershatsky <esq@lawlist.com>
> CC: emacs-devel@gnu.org
> Subject: Re: Drawing dirty rectangles with expose_window:  row->clip = fr
> 
> > Date: Mon, 01 Apr 2019 18:55:46 -0700
> > From: Keith David Bershatsky <esq@lawlist.com>
> >
> > Even though ns_clip_to_rect returns TRUE, "row->clip = fr;" in expose_window can sometimes prevent glyphs from being drawn within the rectangle that is passed as an argument of ns_clip_to_rect.  This has the effect of permitting fake cursors to be drawn, but then glyphs cannot be drawn on top of hollow/box fake cursors.
> >
> > How can I reconcile a false_positive with ns_clip_to_rect?
> 
> Is the fake cursor entirely inside the rectangle described by 'fr', or
> is it or some of its parts outside?
> 
> > Or, perhaps "row->clip = fr;" in expose_window needs to be adjusted to permit the drawing of glyphs?
> 
> It already is, AFAIU.  Barring bugs, that is.



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

* Re: Drawing dirty rectangles with expose_window:  row->clip = fr
  2019-04-02 16:27 Keith David Bershatsky
@ 2019-04-02 16:51 ` Eli Zaretskii
  0 siblings, 0 replies; 8+ messages in thread
From: Eli Zaretskii @ 2019-04-02 16:51 UTC (permalink / raw)
  To: Keith David Bershatsky; +Cc: emacs-devel

> Date:  Tue, 02 Apr 2019 09:27:44 -0700
> From:  Keith David Bershatsky <esq@lawlist.com>
> Cc:  emacs-devel@gnu.org
> 
> In this example, there is one frame with two windows in a top/bottom equal split.  The top window (*scratch*) does not have any fake cursors.  The bottom window (*MC-TEST*) does have fake cursors.  It appears that expose_window is drawing the mode-line of the top window, and the rectangle extends down into the first line of the bottom window that has fake cursors.  The fake cursors draw on the first line of the bottom window, but the glyphs do not draw on top of the box/hollow cursors.  This happens at the section of expose_window where it has the comment: 
> 
> /* Display the mode line if there is one.  */

I don't think I understand you answer.

What is the height of the mode line? is it 16 pixels or less?  IOW,
how do you conclude that the rectangle 'fr' extends beyond the mode
line?

I also don't understand the meaning of this part:

  The fake cursors draw on the first line of the bottom window, but
  the glyphs do not draw on top of the box/hollow cursors.

Which glyphs "do not draw on top of the box/hollow cursors"?



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

* Re: Drawing dirty rectangles with expose_window:  row->clip = fr
@ 2019-04-02 17:42 Keith David Bershatsky
  0 siblings, 0 replies; 8+ messages in thread
From: Keith David Bershatsky @ 2019-04-02 17:42 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Sorry, I misspoke ... I had erroneously placed a condition that inhibited an important message that we need here.  It is actually the first call to expose_line within expose_window where we see the issue occur, and that is why commenting out "row->clip = fr" makes the issue go away.

The FRAME_BOX_CURSOR is a variant of box/hollow cursors.  The box/hollow cursor family is drawn with NSRectFill, and then draw_glyphs writes a glyph on top of the fake cursor if there is a character there.

EXAMPLE:  On the first line of the bottom window (split frame with even top/bottom windows), we have a sentence:  "This is a test!"  We draw a box/hollow family cursor at HPOS 6, which lands on top of the letter "s".  One or more colored rectangles is/are drawn on top of the letter "s", effectively erasing the letter "s" completely.  draw_glyphs then writes a _new_ letter "s" on top of the colored rectangles.

In the current issue, the colored rectangles are drawn on top of the letter "s" at HPOS 6.  However, the call to draw_glyphs does not result in a _new_ letter "s" being drawn on top of the colored rectangles.  "row->clip = fr" prevents the _new_ letter "s" from being drawn on the glass.

The expose_window XRectangle dimensions are as follows:

    fr->x (0) | fr->y (258) | fr->width (595) | fr->height (16)

The expose_line XRectangle dimensions are as follows:

    r.x (0) | r.y (0) | r.width (591) | r.height (0)

The box/hollow family cursor NSRect dimensions are as follows:

    fx (52) | fy (274) | w (7) | h (16)

The relevant STDERR printout is as follows:

expose_window (2, 274, 591, 0)

A.  expose_window (#<window 6 on *MC-TEST*>):  vpos (0)
    fr->x (0) | fr->y (258) | fr->width (595) | fr->height (16)
    r.x (0) | r.y (0) | r.width (591) | r.height (0)

[expose_line is called]

[expose_area is called]

mc_ns_draw_window_cursor (#<window 6 on *MC-TEST*>):
  x (42) | fx (52) | y (0) | fy (274) | hpos (6) | vpos (0)
  wd (7) | h (16) | RGB (1.000000/0.000000/0.270588)
  cursor_type (FRAMED_BOX_CURSOR) | glyph_flavor (MC_GLYPH)

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

> Date: [04-02-2019 09:51:49] <02 Apr 2019 19:51:49 +0300>
> From: Eli Zaretskii <eliz@gnu.org>
> To: Keith David Bershatsky <esq@lawlist.com>
> CC: emacs-devel@gnu.org
> Subject: Re: Drawing dirty rectangles with expose_window:  row->clip = fr
> 
> > Date:  Tue, 02 Apr 2019 09:27:44 -0700
> > From:  Keith David Bershatsky <esq@lawlist.com>
> > Cc:  emacs-devel@gnu.org
> >
> > In this example, there is one frame with two windows in a top/bottom equal split.  The top window (*scratch*) does not have any fake cursors.  The bottom window (*MC-TEST*) does have fake cursors.  It appears that expose_window is drawing the mode-line of the top window, and the rectangle extends down into the first line of the bottom window that has fake cursors.  The fake cursors draw on the first line of the bottom window, but the glyphs do not draw on top of the box/hollow cursors.  This happens at the section of expose_window where it has the comment:
> >
> > /* Display the mode line if there is one.  */
> 
> I don't think I understand you answer.
> 
> What is the height of the mode line? is it 16 pixels or less?  IOW,
> how do you conclude that the rectangle 'fr' extends beyond the mode
> line?
> 
> I also don't understand the meaning of this part:
> 
>   The fake cursors draw on the first line of the bottom window, but
>   the glyphs do not draw on top of the box/hollow cursors.
> 
> Which glyphs "do not draw on top of the box/hollow cursors"?



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

* Re: Drawing dirty rectangles with expose_window:  row->clip = fr
  2019-04-02  1:55 Drawing dirty rectangles with expose_window: row->clip = fr Keith David Bershatsky
  2019-04-02 14:48 ` Eli Zaretskii
@ 2019-04-02 19:34 ` Alan Third
  1 sibling, 0 replies; 8+ messages in thread
From: Alan Third @ 2019-04-02 19:34 UTC (permalink / raw)
  To: Keith David Bershatsky; +Cc: Emacs Devel

On Mon, Apr 01, 2019 at 06:55:46PM -0700, Keith David Bershatsky wrote:
> 
> How can I reconcile a false_positive with ns_clip_to_rect?

Has ns_clip_to_rect already been called on the same rectangle with a
false result? That false result tells Cocoa to include that area in
the available clipping area in drawRect:.

-- 
Alan Third



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

* Re: Drawing dirty rectangles with expose_window:  row->clip = fr
@ 2019-04-02 20:42 Keith David Bershatsky
  0 siblings, 0 replies; 8+ messages in thread
From: Keith David Bershatsky @ 2019-04-02 20:42 UTC (permalink / raw)
  To: Alan Third; +Cc: Eli Zaretskii, emacs-devel

Thank you, Alan, for reviewing this particular thread.

1.  update_window:  Call to ns_clip_to_rect is FALSE.

2.  expose_window:  Call to ns_clip_to_rect is TRUE.

3.  expose_window:  Call to ns_clip_to_rect is TRUE.

I believe step three (3) is where the fake cursor (box/hollow family) is drawn, and where "row->clip = fr" in expose_window prevents the glyph from being drawn on top of the newly laid fake cursor.  If everything in the core of Emacs is working as it should, then I probably need to come up with a new test to determine whether a glyph can/should be drawn in this situation.  However, I have not yet figured out what kind of a test is needed here.

LEGEND:

"fr->x/y/width/height":  This is the incoming XRectangle value of expose_window.

"r.x/y/width/height":  This is the incoming XRectangle value of expose_line.

"fx/fy/wd/h":  These are the NSRect dimensions of the fake box/hollow family cursor, which appears on the first line of the bottom window in a split frame with equal size top/bottom windows).

STDERR MESSAGES:

redisplay_internal 0

0x11602fd60 (*MC-TEST*): same window start
0x11602fd60 (*MC-TEST*): 1

update_window (#<window 6 on *MC-TEST*>)

mc_draw_row (#<window 6 on *MC-TEST*>):  vpos (0) | hpos (0) | len (16)

mc_ns_draw_window_cursor (#<window 6 on *MC-TEST*>):  ns_clip_to_rect (FALSE)
  x (42) | fx (52) | y (0) | fy (274) | hpos (6) | vpos (0)
  wd (7) | h (16) | RGB (1.000000/0.000000/0.270588)
  cursor_type (FRAMED_BOX_CURSOR) | glyph_flavor (MC_GLYPH)

expose_frame (2, 274, 591, 272)

expose_window (2, 274, 591, 272)

A.  expose_window (#<window 6 on *MC-TEST*>):  vpos (0)
    fr->x (2) | fr->y (274) | fr->width (591) | fr->height (272)
    r.x (0) | r.y (0) | r.width (591) | r.height (272)

[expose_line]

expose_area (0):  start_x (0) | start_hpos (0) | end_hpos (16)

mc_ns_draw_window_cursor (#<window 6 on *MC-TEST*>):  ns_clip_to_rect (TRUE)
  x (42) | fx (52) | y (0) | fy (274) | hpos (6) | vpos (0)
  wd (7) | h (16) | RGB (1.000000/0.000000/0.270588)
  cursor_type (FRAMED_BOX_CURSOR) | glyph_flavor (MC_GLYPH)

expose_frame (0, 258, 595, 16)

expose_window (2, 274, 591, 0)

A.  expose_window (#<window 6 on *MC-TEST*>):  vpos (0)
    fr->x (0) | fr->y (258) | fr->width (595) | fr->height (16)
    r.x (0) | r.y (0) | r.width (591) | r.height (0)

[expose_line]

expose_area (0):  start_x (0) | start_hpos (0) | end_hpos (16)

mc_ns_draw_window_cursor (#<window 6 on *MC-TEST*>):  ns_clip_to_rect (TRUE)
  x (42) | fx (52) | y (0) | fy (274) | hpos (6) | vpos (0)
  wd (7) | h (16) | RGB (1.000000/0.000000/0.270588)
  cursor_type (FRAMED_BOX_CURSOR) | glyph_flavor (MC_GLYPH)

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

> Date: [04-02-2019 12:34:21] <2 Apr 2019 20:34:21 +0100>
> From: Alan Third <alan@idiocy.org>
> To: Keith David Bershatsky <esq@lawlist.com>
> Cc: Emacs Devel <emacs-devel@gnu.org>
> Subject: Re: Drawing dirty rectangles with expose_window:  row->clip = fr
> 
> On Mon, Apr 01, 2019 at 06:55:46PM -0700, Keith David Bershatsky wrote:
> >
> > How can I reconcile a false_positive with ns_clip_to_rect?
> 
> Has ns_clip_to_rect already been called on the same rectangle with a
> false result? That false result tells Cocoa to include that area in
> the available clipping area in drawRect:.
> 
> --
> Alan Third



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

* Re: Drawing dirty rectangles with expose_window:  row->clip = fr
@ 2019-04-03 19:28 Keith David Bershatsky
  0 siblings, 0 replies; 8+ messages in thread
From: Keith David Bershatsky @ 2019-04-03 19:28 UTC (permalink / raw)
  To: Alan Third; +Cc: Eli Zaretskii, emacs-devel

After some additional testing and digging into the core code of Emacs, I made the following observations:

. ns_draw_window_cursor calls ns_clip_to_rect, which does _not_ take "row->clip" into consideration when drawing cursors with NSRectFill.

. When it comes time to draw glyphs on top of the box/hollow family of cursors, "row->clip" is taken into consideration by get_glyph_string_clip:

  if (s->row->clip)
    {
      XRectangle r_save = r;
      if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
        r.width = 0;
    }

Inasmuch as fake cursors are drawn immediately following calls to draw_glyphs (e.g., during expose_window), I have created a slightly modified version of ns_clip_to_rect that takes "row->clip" into consideration and calls an NS version of x_intersect_rectangles ...  In a few tests, this approach appears to be achieving the desired results.

Keith



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

end of thread, other threads:[~2019-04-03 19:28 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-02  1:55 Drawing dirty rectangles with expose_window: row->clip = fr Keith David Bershatsky
2019-04-02 14:48 ` Eli Zaretskii
2019-04-02 19:34 ` Alan Third
  -- strict thread matches above, loose matches on Subject: below --
2019-04-02 16:27 Keith David Bershatsky
2019-04-02 16:51 ` Eli Zaretskii
2019-04-02 17:42 Keith David Bershatsky
2019-04-02 20:42 Keith David Bershatsky
2019-04-03 19:28 Keith David Bershatsky

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).