[gsharp-devel] clipping regions, replay, handle-repaint
Christophe Rhodes
csr21 at cam.ac.uk
Wed May 24 10:02:59 UTC 2006
Hi,
I think that CLIM underspecifies how clipping regions (and text-styles
and line-styles) are handled for output records. For
REPLAY-OUTPUT-RECORD, it says
"The current user transformation, line style, text style, ink, and
clipping region of stream are all ignored during the replay
operation. Instead, these are gotten from the output record."
which is good, but unfortunately it doesn't specify /how/ they are
gotten, which means that implementing one's own output record class is
tricky.
Why does this matter? In gsharp, we implement sloped beams with our
own kind of output record; as of this morning, I taught that output
record, and the replay-output-record methods, about the medium
clipping region, so that sloped short beams (as in
<http://www-jcsu.jesus.cam.ac.uk/~csr21/sloped-short-beams.png>)
survive repainting; previously the output record had no record of the
clipping region, and so a repaint would cause the entire width, rather
than just the short segment, to be drawn. So this now works
acceptably.
However, we implement horizontal beams with an ordinary rectangle, and
short ones with an ordinary rectangle and clipping region. Before a
repaint, this works fine: see
<http://www-jcsu.jesus.cam.ac.uk/~csr21/horizontal-beams.png>.
However, obscuring and uncovering the window, triggering a repaint,
results in
<http://www-jcsu.jesus.cam.ac.uk/~csr21/horizontal-beams-after-repaint.png>.
This happens because the replay-output-record methods for the clim
internal graphics things (such as rectangles) set the medium clipping
region while they're replaying, but don't set it back; they simply
rely on a method on replay. In fact, in McCLIM itself as distributed
the set-medium-graphics-state :after method on gs-clip-mixin is
essentially disabled, though I'm not entirely sure why; gsharp
re-enables it, presumably in an attempt to get some of this working,
but disabling it again simply means that replaying horizontal beams
(i.e. rectangles) which have been clipped ignores the previous
clipping region.
What is one to do? Well, I think with the standard as it is there's
no way of writing output record classes. However, the case of
changing ink can be handled in the spec, as CLIM specifies a function
displayed-output-record-ink; using that, dealing with the ink looks like
(defmethod replay-output-record :around
((record displayed-output-record) stream ...)
(let ((medium (sheet-medium stream)))
(with-drawing-options (medium :ink (displayed-output-record-ink record))
(call-next-method))))
and this will work, given that all displayed-output-record objects
obey the displayed-output-record protocol. If we were to extend the
protocol to require displayed-output-record-clipping-region,
displayed-output-record-text-style and
displayed-output-record-line-style, then I think this would cover the
difficult cases, most of the set-medium-graphics-state methods could
go away, and gsharp could have horizontal short beams.
Comments?
Cheers,
Christophe
More information about the gsharp-devel
mailing list