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