[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Off-screen drawing probl



        Reply to:   RE>Off-screen drawing problem
Here is a very simple class that I wrote which you can mix into
any view.  Just make sure that any drawing commands called from
view-draw-contents call the Macintosh tool traps
directly and draw to the current port, and don't use any calls
to with-focused-view (which will set the port back to the
window, instead of the offscreen bitmap), and the
(VIEW-DRAW-CONTENTS :AROUND) method will automatically set the
port to the offscreen bitmap, call the next view-draw-contents
method, restore the port back to the window's grafport, and copy
the bits from the offscreen bitmap to the current port.  I was
just doing black-and-white graphics so I wasn't careful about
bitmap depth, so you might want to modify the arguments to
#_NewGWorld if necessary.

(defclass offscreen-view (view)
  ((gworld :accessor gworld))
  )

(defmethod initialize-instance :after ((offscreen
offscreen-view) &rest initargs)
  (declare (ignore initargs))
  (rlet ((bounds :rect :topleft 0 :bottomright (view-size
offscreen))
         (gw :pointer))
    (let ((result (#_newgworld gw
                   8 
                   bounds
                   (%null-ptr)
                   (%null-ptr)
                   0))
          (macptr (%null-ptr)))
      (assert (zerop result) () "Error creating gworld")
      (%setf-macptr macptr (%get-ptr gw))
      (setf (gworld offscreen) macptr))))

(defmethod remove-view-from-window :after ((offscreen
offscreen-view))
  (#_DisposeGWorld (gworld offscreen)))

(defmethod view-draw-contents :around ((view offscreen-view))
  (unwind-protect 
    (let ((pixmap-handle (#_GetGWorldPixmap (gworld view))))
      (rlet ((port :pointer)
             (gdevice :pointer)
             (rect :rect :topleft #@(0 0) :bottomright
(view-size view)))
        (#_LockPixels pixmap-handle)
        (unwind-protect 
          (progn 
            (#_GetGWorld port gdevice)
            (#_SetGWorld (gworld view) (%null-ptr))
            (#_EraseRect rect)
            (call-next-method view))
          (#_SetGWorld (%get-ptr port) (%get-ptr gdevice)))
        (with-pointers ((pm pixmap-handle)
                        (db (rref (wptr view)
grafport.portbits)))
          (#_CopyBits pm db rect rect #$srcCopy (%null-ptr)))
        ))
    (#_unlockpixels (#_GetGWorldPixmap (gworld view)))))