home *** CD-ROM | disk | FTP | other *** search
- (in-package :oou)
- (oou-provide :PICT-u)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; PICT-u.Lisp
- ;;
- ;; Copyright ⌐ 1992 Northwestern University Institute for the Learning Sciences
- ;; All Rights Reserved
- ;;
- ;; author: Michael S. Engber
- ;;
- ;; utilities for PICTs
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (oou-dependencies
- :records-u
- :QuickDraw-u
- :+Files
- :+Devices)
-
- (export '(get-picture-from-file
- write-picture-to-file
- get-PICT-file-info
- draw-picture-from-file
- ))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- (eval-when (:compile-toplevel :load-toplevel :execute)
-
- (defmacro with-PICT-file ((pathname refNum PICT-size PICT-record
- &key
- (direction :input)
- (if-does-not-exist (ecase direction (:input :error) (:output :create)))
- (if-exists :error)
- (creator "????"))
- &body body)
- (let ((fn (gensym)))
- `(flet ((,fn (,refNum ,PICT-size ,PICT-record) ,@body))
- (declare (dynamic-extent #',fn))
- (call-with-PICT-file ,pathname #',fn
- :direction ,direction
- :if-does-not-exist ,if-does-not-exist
- :if-exists ,if-exists
- :creator ,creator))))
-
- )
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- (defun get-picture-from-file (pathname)
- ;;Returns a PICT handle from the specified PICT file.
- (with-PICT-file (pathname refnum PICT-size PICT-record)
- (let ((PICT-handle (#_NewHandle PICT-size)))
- (if (%null-ptr-p PICT-handle)
- (error "unable to allocate a ~a byte PICT handle for ~s." PICT-size pathname)
- (with-dereferenced-handles ((PICT_p PICT-handle))
- (pset PICT_p :Picture PICT-record)
- (%incf-ptr PICT_p (rlength :Picture))
- (rlet ((byteCount_p :long (- PICT-size (rlength :Picture))))
- (let ((ecode (#~FSRead refnum byteCount_p PICT_p)))
- (unless (and (zerop ecode) (= (- PICT-size (rlength :Picture)) (%get-long byteCount_p)))
- (error "(~a) calling FSRead. Read ~a/~a bytes of PICT data from ~s."
- ecode (%get-long byteCount_p) PICT-size pathname))))))
- PICT-handle)))
-
-
- (defun write-picture-to-file (PICT-handle pathname &key (creator "????") (if-exists :error))
- ;;Creates a PICT file containing PICT-handle.
- (with-PICT-file (pathname refNum dummy-size PICT-record
- :direction :output
- :if-exists if-exists
- :creator creator)
- (declare (ignore dummy-size PICT-record))
- (let ((PICT-size (#_GetHandleSize PICT-handle)))
- (rlet ((byteCount_p :long PICT-size))
- (with-dereferenced-handles ((PICT_p PICT-handle))
- (let ((ecode (#~FSWrite refnum byteCount_p PICT_p)))
- (unless (and (zerop ecode) (= PICT-size (%get-long byteCount_p)))
- (error "(~a) calling FSWrite. Wrote ~a/~a bytes of PICT data from ~s."
- ecode (%get-long byteCount_p) PICT-size pathname)))))
- pathname)))
-
-
- (defun get-PICT-file-info (pathname picture-record-ptr)
- ;;Returns the size (in bytes) of the PICT in the specified PICT file.
- ;;picture-record-ptr's picFrame is filled in.
- (with-PICT-file (pathname refnum PICT-size PICT-record)
- (declare (ignore refnum))
- (pset picture-record-ptr :Picture PICT-record)
- PICT-size))
-
-
- ;;QuickDraw bottle neck routine for getPicProc that reads PICT
- ;;data from an open file. see IM V pp. 87-89
- (defpascal dpfd-StdGetPic (:ptr dataPtr :word byteCount)
- (declare (special *dpfd-refNum*))
- (rlet ((byteCount_p :long byteCount))
- (#~FSRead *dpfd-refNum* byteCount_p dataPtr)))
-
-
- (defun draw-picture-from-file (pathname rect &optional (scale-to-rect-p t))
- ;;Draws the specfied PICT file either scaledd to rect or at the topLeft
- ;;corner of rect. The PICT size (in bytes) is returned.
- (let ((PICT_h (#_NewHandle (rlength :Picture))))
- (when (%null-ptr-p PICT_h)
- (error "unable to allocate a ~a temporary picture record handle (~a bytes) for ~s." (rlength :Picture) pathname))
- (unwind-protect
- (with-PICT-file (pathname refnum PICT-size PICT-record)
- (with-dereferenced-handles ((PICT_p PICT_h))
- (pset PICT_p :Picture PICT-record))
- (rlet ((r :Rect
- :topLeft (pref rect :Rect.topLeft)
- :botRight (if scale-to-rect-p
- (pref rect :Rect.botRight)
- (add-points (pref rect :Rect.topLeft)
- (subtract-points (href PICT_h :Picture.picFrame.botRight)
- (href PICT_h :Picture.picFrame.topLeft))))))
- (let ((*dpfd-refNum* refNum))
- (declare (special *dpfd-refNum*))
- (without-interrupts
- (with-QDProcs (:getPicProc dpfd-StdGetPic)
- (#_DrawPicture PICT_h r)))))
- PICT-size)
- (#_DisposeHandle PICT_h))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- (defun call-with-PICT-file (pathname fn &key
- (direction :input)
- (if-does-not-exist (ecase direction (:input :error) (:output :create)))
- (if-exists :error)
- (creator "????"))
- (let ((set-EOF-p nil))
- (if (probe-file pathname)
- (ecase direction
- (:input )
- (:output (ecase if-exists
- (:error (error "~s already exists." pathname))
- (:overwrite (setf set-EOF-p t)))))
- (ecase direction
- (:input (error "~s doesn't exist - can't open for input." pathname))
- (:output (ecase if-does-not-exist
- (:error (error "~s does not exist." pathname))
- (:create (with-pstrs ((filename (mac-namestring pathname)))
- (let ((ecode (#~Create filename 0 creator "PICT")))
- (unless (zerop ecode)
- (error "(~a) attempting to create ~s." ecode pathname))))
- (setf set-EOF-p t))))))
-
- (unless (eq (mac-file-type pathname) :PICT)
- (error "~s is not a PICT file." pathname))
-
- (let ((refNum (with-pstrs ((fileName (mac-namestring pathname)))
- (rlet ((refNum_p :integer))
- (let ((ecode (#~FSOpen fileName 0 refNum_p)))
- (unless (zerop ecode) (error "(~a) opening file: ~s." ecode pathname))
- (%get-word refNum_p))))))
- (unwind-protect
- (rlet ((PICT-record :Picture))
-
- (when set-EOF-p
- (let ((ecode (#~SetEOF refNum 512)))
- (unless (zerop ecode) (error "(~a) calling SetEOF on ~s." ecode pathname))))
-
- (let ((file-size (rlet ((logicalEOF_p :long))
- (let ((ecode (#~GetEOF refNum logicalEOF_p)))
- (unless (zerop ecode) (error "(~a) calling GetEOF on ~s." ecode pathname))
- (%get-long logicalEOF_p)))))
-
- (ecase direction
- (:input
- ;read the PICT header & leave file position just beyond (+ 512 (rlength :Picture))
- (let ((ecode (#~SetFPos refNum #$fsFromStart 512)))
- (unless (zerop ecode) (error "(~a) calling SetFPos (preparing to read picture record) on ~s." ecode pathname)))
- (rlet ((byteCount_p :long (rlength :Picture)))
- (let ((ecode (#~FSRead refnum byteCount_p PICT-record)))
- (unless (and (zerop ecode) (= (rlength :Picture) (%get-long byteCount_p)))
- (error "(~a) calling PBRead. Read ~a bytes of PICT header data from ~s."
- ecode (%get-long byteCount_p) pathname)))))
- (:output
- ;set the file position to 512 & invalidate PICT-record passed to fn
- (%setf-macptr PICT-record (%null-ptr))
- (let ((ecode (#~SetFPos refNum #$fsFromStart 512)))
- (unless (zerop ecode) (error "(~a) calling SetFPos (preparing to write picture record) on ~s." ecode pathname)))))
-
-
- (funcall fn refNum (- file-size 512) PICT-record)))
- (#~FSClose refNum)))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- #|
-
- (defparameter *test-w* (make-instance 'window :color-p t))
-
- (with-focused-view *test-w*
- (rlet ((r :Rect :topLeft 0 :botRight (view-size *test-w*)))
- (draw-picture-from-file "oou:examples;MrT.PICT" r nil)))
-
- (invalidate-view *test-w* t)
-
- (defparameter *p-handle* (get-picture-from-file "oou:examples;MrT.PICT"))
-
- (rlet ((r :Rect :topLeft #@(100 100) :botRight #@(300 300)))
- (with-focused-view *test-w* (#_DrawPicture *p-handle* r)))
-
- (invalidate-view *test-w* t)
-
- (write-picture-to-file *p-handle* "HD:temp")
-
- (with-focused-view *test-w*
- (rlet ((r :Rect :topLeft 0 :botRight (view-size *test-w*)))
- (draw-picture-from-file "HD:temp" r nil)))
-
- (#_DisposeHandle *p-handle*)
-
- (rlet ((p :Picture))
- (print (get-PICT-file-info "oou:examples;MrT.PICT" p))
- (terpri)
- (print-record (pref p :Picture.picFrame) :Rect)
- (print (pref p :Picture.picSize)))
-
- |#