Lisp HUG Maillist Archive

RE: Pinboard-object clipping

Hi Denis,

Thanks for the suggestion - I've already experimented quite a bit with pixmaps. The problem is that my drawing is always scaled to the current size of the pane, and since I don't want to be creating and destroying pixmaps on every resize event I get buffered drawing in that case via :draw-pinboard-objects :buffer. So long as I'm not resizing I do indeed draw to a backing pixmap, and blit from that. On resizing I destroy the pixmap and draw directly to the pane (I can't simply rescale an image, since I'm drawing audio waveforms, which need to be down-sampled for efficient drawing, and when resizing an image upwards the down-sampled nature of the data becomes apparent). When resizing is completed (I detect this with a timer method based on a suggestion by David McClain) I create a fresh pixmap, which is cached until a new resize event occurs.

Of course Windows by default clears a pane to the background colour on every paint event. I switch this off with:

(defmethod capi-internals:simple-pane-erase-background
                 ((self canvas)) ; My pinboard-layout subclass.
  nil)

This completely removes any residual flicker, but means I can't then rely on a display-callback to the canvas to get the clip-region (because nothing gets cleared). But when I try and obtain it via draw-pinboard-object I get that odd inconsistency demonstrated by the test code in my original post....

My current work-around is to handle scroll clipping myself, but leave all other clipping to the CAPI. This is not too difficult - all I do is detect when a scroll event has occurred, and calculate the clip-rect as the difference between the current and previous viewport bounding-boxes. When not scrolling I can just use the x, y, width and height args to my draw-pinboard-object method, which, as the test code shows, seem to yield the expected results at least for non-scrolled clipping.

This works, but it's all rather cumbersome and inelegant, and I'm sure I shouldn't have to do it like this.

Many thanks,
Chris


Date: Wed, 17 Mar 2010 21:34:35 +0100
Subject: Re: Pinboard-object clipping
From: denis.pousseur@gmail.com
To: relativeflux@hotmail.co.uk
CC: lisp-hug@lispworks.com

Re: Pinboard-object clipping It’s strange...
Maybe can you work around with a pixmap-graphic-port and do the buffering yourself ? For my experience this is the better way to have a nice result without flickering.
Draw directly the clipping region in the pixmap (so you can use :draw-pinboard-objects t and the clipping region will be correct) then copy the pixels to the real port (so no need to clear it before) : It’s not a lot of work and the result is absolutely perfect.

Best

Denis

Le 17/03/10 20:44, « [NOM] » <[ADRESSE]> a écrit :

> (defclass po (capi:pinboard-object)
>     ()
>     (:default-initargs
>    :x 0
>        :y 0
>        :width 3000
>        :height 300))
>
> (defparameter *po-clip-rects* nil)
>
> (defmethod capi:draw-pinboard-object (pinboard (object po)
>                                                                                             &key x y width height
>                                                                                             &allow-other-keys)
>     (declare (ignore pinboard object))
>     (push (list x y width height) *po-clip-rects*))
>
> (capi:contain (make-instance 'capi:pinboard-layout
>                                                                     :description (list (make-instance 'po))
>                                                                      :scroll-width 3000
>                                              :horizontal-scroll t
>                                         :fit-size-to-children nil ))
>                                                     ;:draw-pinboard-objects :buffer))
>                                                                      ;Uncomment this then inspect *po-clip-rects*.


-------------------------------------------------------
Denis Pousseur
70 rue de Wansijn
1180 Bruxelles, Belgique

Tel : 32 (0)2 219 31 09
Mail :  denis.pousseur@gmail.com
-------------------------------------------------------


Do you want a Hotmail account? Sign-up now - Free

Re: Pinboard-object clipping

Re: Pinboard-object clipping Hi Chris,

I do some similar... but finally I don’t draw anything during resizing, I redraw completely the pane when resizing is finished. It’s not the best solution but, well, I think that for the user, during resizing, the most important is that the process is fast and fluid. With a very complex capi-pane, the resizing operation is already very slow, so if I draw moreover, it becomes impossible on a non recent machine (even on a power pc G5 witch is not so old...).

To avoid the system calls to clear-rectangle, I subclass invalidate-rectangle. Apparently, the call to clear-rectangle is in the graphic-port-mixin method of invalidate-rectangle. This way, you can continue to work with display-callback in any situations (your method of invalidate-rectangle must call your display-callback)

Best

Denis


Le 18/03/10 8:35, « [NOM] » <[ADRESSE]> a écrit :

Hi Denis,

Thanks for the suggestion - I've already experimented quite a bit with pixmaps. The problem is that my drawing is always scaled to the current size of the pane, and since I don't want to be creating and destroying pixmaps on every resize event I get buffered drawing in that case via :draw-pinboard-objects :buffer. So long as I'm not resizing I do indeed draw to a backing pixmap, and blit from that. On resizing I destroy the pixmap and draw directly to the pane (I can't simply rescale an image, since I'm drawing audio waveforms, which need to be down-sampled for efficient drawing, and when resizing an image upwards the down-sampled nature of the data becomes apparent). When resizing is completed (I detect this with a timer method based on a suggestion by David McClain) I create a fresh pixmap, which is cached until a new resize event occurs.

Of course Windows by default clears a pane to the background colour on every paint event. I switch this off with:

(defmethod capi-internals:simple-pane-erase-background
                 ((self canvas)) ; My pinboard-layout subclass.
  nil)

This completely removes any residual flicker, but means I can't then rely on a display-callback to the canvas to get the clip-region (because nothing gets cleared). But when I try and obtain it via draw-pinboard-object I get that odd inconsistency demonstrated by the test code in my original post...

My current work-around is to handle scroll clipping myself, but leave all other clipping to the CAPI. This is not too difficult - all I do is detect when a scroll event has occurred, and calculate the clip-rect as the difference between the current and previous viewport bounding-boxes. When not scrolling I can just use the x, y, width and height args to my draw-pinboard-object method, which, as the test code shows, seem to yield the expected results at least for non-scrolled clipping.

This works, but it's all rather cumbersome and inelegant, and I'm sure I shouldn't have to do it like this.

Many thanks,
Chris


Date: Wed, 17 Mar 2010 21:34:35 +0100
Subject: Re: Pinboard-object clipping
From: denis.pousseur@gmail.com
To: relativeflux@hotmail.co.uk
CC: lisp-hug@lispworks.com

Re: Pinboard-object clipping It’s strange...
Maybe can you work around with a pixmap-graphic-port and do the buffering yourself ? For my experience this is the better way to have a nice result without flickering.
Draw directly the clipping region in the pixmap (so you can use :draw-pinboard-objects t and the clipping region will be correct) then copy the pixels to the real port (so no need to clear it before) : It’s not a lot of work and the result is absolutely perfect.

Best

Denis

Le 17/03/10 20:44, « [NOM] » <[ADRESSE]> a écrit :

> (defclass po (capi:pinboard-object)
>     ()
>     (:default-initargs
>    :x 0
>        :y 0
>        :width 3000
>        :height 300))
>
> (defparameter *po-clip-rects* nil)
>
> (defmethod capi:draw-pinboard-object (pinboard (object po)
>                                                                                             &key x y width height
>                                                                                             &allow-other-keys)
>     (declare (ignore pinboard object))
>     (push (list x y width height) *po-clip-rects*))
>
> (capi:contain (make-instance 'capi:pinboard-layout
>                                                                     :description (list (make-instance 'po))
>                                                                      :scroll-width 3000
>                                              :horizontal-scroll t
>                                         :fit-size-to-children nil ))
>                                                     ;:draw-pinboard-objects :buffer))
>                                                                      ;Uncomment this then inspect *po-clip-rects*.


-------------------------------------------------------
Denis Pousseur
70 rue de Wansijn
1180 Bruxelles, Belgique

Tel : 32 (0)2 219 31 09
Mail :  denis.pousseur@gmail.com
-------------------------------------------------------
       

Do you want a Hotmail account? Sign-up now - Free <http://clk.atdmt.com/UKM/go/197222280/direct/01/>


-------------------------------------------------------
Denis Pousseur
70 rue de Wansijn
1180 Bruxelles, Belgique

Tel : 32 (0)2 219 31 09
Mail :  denis.pousseur@gmail.com
-------------------------------------------------------
Updated at: 2020-12-10 08:39 UTC