;;; -*- Mode: LISP; Syntax: Zetalisp; Package: DVI; Base: 10 -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Buffer I/O routines ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (eval-when (eval compile load) (defmacro bpeek-byte (buff) `(aref ,buff (fill-pointer ,buff))) (defmacro bget-byte (buff) ;; return the next 8 bits from the input ;; stream `(progn (incf (fill-pointer ,buff)) (aref ,buff (1- (fill-pointer ,buff))))) (defmacro bget-signed-byte (buff) `(let ((b (bget-byte ,buff))) (if (< b 128) b (- b 256)))) (defmacro bget-2-bytes (buff) `(let* ((a (aref ,buff (fill-pointer ,buff))) (b (aref ,buff (1+ (fill-pointer ,buff))))) (incf (fill-pointer ,buff) 2) (logior (lsh a 8) b))) ;; a * 256 + b (defmacro bsigned-pair (buff) `(let* ((a (aref ,buff (fill-pointer ,buff))) (b (aref ,buff (1+ (fill-pointer ,buff))))) (incf (fill-pointer ,buff) 2) (if (< a 128) (logior (lsh a 8) b) (logior (lsh (- a 256) 8) b)))) (defmacro bget-3-bytes (buff) `(let* ((a (aref ,buff (fill-pointer ,buff))) (b (aref ,buff (1+ (fill-pointer ,buff)))) (c (aref ,buff (+ 2 (fill-pointer ,buff))))) (incf (fill-pointer ,buff) 3) (logior (lsh a 16) (lsh b 8) c))) (defmacro bsigned-trio (buff) `(let* ((a (aref ,buff (fill-pointer ,buff))) (b (aref ,buff (1+ (fill-pointer ,buff)))) (c (aref ,buff (+ 2 (fill-pointer ,buff))))) (incf (fill-pointer ,buff) 3) (if (< a 128) (logior (lsh a 16) (lsh b 8) c) (logior (lsh (- a 256) 16)(lsh b 8) c)))) (defmacro bsigned-quad (buff) `(let* ((a (aref ,buff (fill-pointer ,buff))) (b (aref ,buff (1+ (fill-pointer ,buff)))) (c (aref ,buff (+ 2 (fill-pointer ,buff)))) (d (aref ,buff (+ 3 (fill-pointer ,buff))))) (incf (fill-pointer ,buff) 4) (if (< a 128) (logior (ash a 24)(lsh b 16)(lsh c 8) d) (logior (ash (- a 256) 24)(lsh b 16)(lsh c 8) d)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Binary file I/O routines ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defmacro peek-byte (istr) `(send ,istr :tyipeek)) (defmacro get-byte (istr) ;; return the next 8 bits from the input ;; stream `(send ,istr :tyi)) ;; handler for eof? (defmacro get-signed-byte (istr) `(let ((b (send ,istr :tyi))) (if (< b 128) b (- b 256)))) (defmacro get-2-bytes (istr) `(let* ((a (send ,istr :tyi)) (b (send ,istr :tyi))) (logior (lsh a 8) b))) ;; a * 256 + b (defmacro signed-pair (istr) `(let* ((a (send ,istr :tyi)) (b (send ,istr :tyi))) (if (< a 128) (logior (lsh a 8) b) (logior (lsh (- a 256) 8) b)))) (defmacro get-3-bytes (istr) `(let* ((a (send ,istr :tyi)) (b (send ,istr :tyi)) (c (send ,istr :tyi))) (logior (lsh a 16) (lsh b 8) c))) (defmacro signed-trio (istr) `(let* ((a (send ,istr :tyi)) (b (send ,istr :tyi)) (c (send ,istr :tyi))) (if (< a 128) (logior (lsh a 16) (lsh b 8) c) (logior (lsh (- a 256) 16)(lsh b 8) c)))) ;;i.e.((a-256) * 256 + b) * 256 + c (defmacro signed-quad (istr) `(let* ((a (send ,istr :tyi)) (b (send ,istr :tyi)) (c (send ,istr :tyi)) (d (send ,istr :tyi))) (if (< a 128) (logior (ash a 24)(lsh b 16)(lsh c 8) d) (logior (ash (- a 256) 24)(lsh b 16)(lsh c 8) d)))) ) (defmacro write-byte (ostr byte) `(send ,ostr :tyo ,byte)) (defmacro write-2-bytes (ostr bytes) `(progn (send ,ostr :tyo (ldb (byte 8 8) ,bytes)) (send ,ostr :tyo (ldb (byte 8 0) ,bytes)))) (defmacro write-buffer (buff byte) `(array-push-extend ,buff ,byte)) (defmacro write2-buffer (buff bytes) `(progn (array-push-extend ,buff (ldb (byte 8 8) ,bytes)) (array-push-extend ,buff (ldb (byte 8 0) ,bytes)))) ;; go to the end of the file. (defmacro go-eof (istr) `(send ,istr :set-pointer (1- (file-stream-length ,istr)))) (defmacro skip-bytes (istr n) ;;go forward n bytes, n can be negative `(send ,istr :set-pointer (+ (send ,istr :read-pointer) ,n))) (defsubst move-back (file-buffer n) ;;move back the dvi file by n pages (let (prev-page-ptr) (dotimes (i n) (if ( (bget-byte file-buffer) bop)(bad-dvi "Missing bop")) (incf (fill-pointer file-buffer) 40) ;get rid of c0 to c9 params (setq prev-page-ptr (bsigned-quad file-buffer)) (if (> prev-page-ptr 0) (setf (fill-pointer file-buffer) prev-page-ptr) (decf (fill-pointer file-buffer) 44))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; subroutines for unit conversions. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar conv) (defvar dvis-per-fix) (defvar dvi2mica) ;; ;; compute the number of pixels in the height or width of a rule. ;; (defsubst rule-pixels (x) (ceiling (* conv x))) ;;convert from dvi units to pixels (defsubst pixel-round (x) (round (* conv x))) (defsubst dvi-round (x) (// x (float conv))) ;; (defsubst fix2dvi (x) (* dvis-per-fix x)) ;; (defsignal dvi-error error ()) (defun bad-dvi (reason &rest args) (if args (lexpr-funcall 'ferror 'dvi-error reason args) (ferror 'dvi-error "Bad dvi: ~S" reason))) (deff bad-pxl 'bad-dvi) (defmacro get-fntnum (texfntnum array) `(loop for i from 0 below (fill-pointer ,array) do (if (= (aref ,array i) ,texfntnum) (return i)))) (defmacro file-length (fbuffer) `(array-leader ,fbuffer 1)) (defmacro store-file-length (fbuffer length) `(store-array-leader ,length ,fbuffer 1)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;The following macros are for handling PRESS files ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Puts out command to show characters on the DL. ;;; Uses Show-characters-short if possible. (defmacro put-pending-characters () `(when (plusp pending-characters) (loop until (< pending-characters 256.) do (el-byte ) (el-byte 255.) (decf pending-characters 255.) finally (cond ((> pending-characters 32.) (el-byte ) (el-byte pending-characters)) ((plusp pending-characters) (el-byte (1- (+ pending-characters)))))) (setq pending-characters 0))) ;;; Insert a byte into the EL. (defmacro el-byte (byte) `(progn (array-push-extend page-entity-buffer ,byte entity-buffer-extension-size) (incf entity-list-length))) ;;; Insert a word into the EL. (defmacro el-word (word) (once-only (word) `(progn (el-byte (ldb #o1010 ,word)) (el-byte (ldb #o0010 ,word))))) ;;; Insert a 32-bit word into the EL. (defmacro el-32word (word) (once-only (word) `(progn (el-byte (ldb #o3010 ,word)) (el-byte (ldb #o2010 ,word)) (el-byte (ldb #o1010 ,word)) (el-byte (ldb #o0010 ,word))))) ;;; Insert a byte into the DL. (defmacro dl-byte (byte) `(progn (send output-stream :tyo ,byte) (incf data-list-length))) ;;; Insert a word into the DL. (defmacro dl-word (word) (once-only (word) `(progn (dl-byte (ldb #o1010 ,word)) (dl-byte (ldb #o0010 ,word))))) ;;; Insert a 32-bit word into the DL. (defmacro dl-32word (word) (once-only (word) `(progn (dl-byte (ldb #o3010 ,word)) (dl-byte (ldb #o2010 ,word)) (dl-byte (ldb #o1010 ,word)) (dl-byte (ldb #o0010 ,word))))) ;;; File I/O. (defmacro byte-out (byte) `(send output-stream :tyo ,byte)) (defmacro word-out (word) (once-only (word) `(progn (byte-out (ldb #o1010 ,word)) (byte-out (ldb #o0010 ,word))))) ;;; Output a BCPL string. (defmacro bcpl-out (string max-length) `(let ((string-end (min (1+ (string-length ,string)) ,max-length))) (byte-out (1- string-end)) (send output-stream :string-out ,string 0 (1- string-end)) (pad-bytes-out (- ,max-length string-end)))) (defmacro pad-bytes-out (number) `(loop repeat ,number do (byte-out 0))) (defun open-8b-input (filename) ;; using :characters NIL can confuse some servers into 16 bit mode. ;; (open filename :direction :input :characters nil :byte-size 8) ;; :raw T is quaint but works. (let ((pathname (send (fs:parse-pathname filename) :translated-pathname))) (cond ((eq :lispm (send pathname :system-type)) (open filename :direction :input)) ('else (open filename :direction :input :raw t))))) (defun open-8b-output (filename) (let ((pathname (send (fs:parse-pathname filename) :translated-pathname))) (cond ((eq :lispm (send pathname :system-type)) (open filename :direction :output)) ('else (open filename :direction :output :raw t))))) (defun file-stream-length (file-stream) ;; if we used :characters NIL and :byte-size 8 ;; then some unix servers were give the wrong length. ;; but since we dont, we win. (send file-stream :length)) (defvar *pxl-filename-prepend* "tex: TeXfonts;") (defvar *tfm-filename-prepend* "tex: TeXfonts;")