home *** CD-ROM | disk | FTP | other *** search
- ;; -*- Mode:LISP; Package:BOXER; Base:10.;fonts:cptfont,cptfontb; -*-
- #|
-
- Copyright 1984 Massachusetts Institute of Technology
-
- Permission to use, copy, modify, distribute, and sell this software
- and its documentation for any purpose is hereby granted without fee,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of M.I.T. not be used in
- advertising or publicity pertaining to distribution of the software
- without specific, written prior permission. M.I.T. makes no
- representations about the suitability of this software for any
- purpose. It is provided "as is" without express or implied warranty.
-
-
- +-Data--+
- This file is part of the | BOXER | system
- +-------+
-
- This contains all of the Interface between Graphics sheets
- and the rest of the BOXER Editor. The functions and methods
- which manipulate pixels (as opposed to graphics objects) can
- also be found here In particular, the functions which are
- used to draw lines, regions, etc are here.
-
- |#
-
- ;;; get the offsets right
-
- (DEFMACRO WITH-TURTLE-SLATE-ORIGINS (SCREEN-BOX &BODY BODY)
- ;; this macro sets x and y coordinates of top left of turtle array
- ;; not that the a SCREEN-SHEET may NOT have been allocated if this has been called BEFORE
- ;; Redisplay has had a chnace to run
- `(LET ((SCREEN-SHEET (TELL-CHECK-NIL ,SCREEN-BOX :SCREEN-SHEET)))
- (UNLESS (NULL SCREEN-SHEET)
- (MULTIPLE-VALUE-BIND (BOX-X-OFFSET BOX-Y-OFFSET)
- (TELL ,SCREEN-BOX :POSITION)
- (MULTIPLE-VALUE-BIND (SHEET-X SHEET-Y)
- (GRAPHICS-SCREEN-SHEET-OFFSETS SCREEN-SHEET)
- (LET ((%ORIGIN-X-OFFSET (+ (TV:SHEET-INSIDE-LEFT *BOXER-PANE*)
- BOX-X-OFFSET
- SHEET-X))
- (%ORIGIN-Y-OFFSET (+ (TV:SHEET-INSIDE-TOP *BOXER-PANE*)
- BOX-Y-OFFSET
- SHEET-Y)))
- (PROGN . ,BODY)))))))
-
- (DEFVAR *SCRUNCH-FACTOR* 1
- "the factor used to normalize the Y-coordinates so that squares really are")
-
- (DEFUN MAKE-GRAPHICS-SHEET (WID HEI &OPTIONAL BOX)
- (%MAKE-GRAPHICS-SHEET WID HEI (TV:MAKE-SHEET-BIT-ARRAY *BOXER-PANE* WID HEI) BOX))
-
- (DEFUN MAKE-GRAPHICS-SCREEN-SHEET (ACTUAL-OBJ &OPTIONAL (X-OFFSET 0.) (Y-OFFSET 0.))
- (%MAKE-G-SCREEN-SHEET ACTUAL-OBJ X-OFFSET Y-OFFSET))
-
- (DEFUN GRAPHICS-SCREEN-SHEET-OFFSETS (GRAPHICS-SCREEN-SHEET)
- (VALUES (GRAPHICS-SCREEN-SHEET-X-OFFSET GRAPHICS-SCREEN-SHEET)
- (GRAPHICS-SCREEN-SHEET-Y-OFFSET GRAPHICS-SCREEN-SHEET)))
-
- (DEFUN SET-GRAPHICS-SCREEN-SHEET-X-OFFSET (GRAPHICS-SCREEN-SHEET NEW-X-OFFSET)
- (SETF (GRAPHICS-SCREEN-SHEET-X-OFFSET GRAPHICS-SCREEN-SHEET) NEW-X-OFFSET))
-
- (DEFUN SET-GRAPHICS-SCREEN-SHEET-Y-OFFSET (GRAPHICS-SCREEN-SHEET NEW-Y-OFFSET)
- (SETF (GRAPHICS-SCREEN-SHEET-Y-OFFSET GRAPHICS-SCREEN-SHEET) NEW-Y-OFFSET))
-
- ;;accessors for graphics boxes
-
- (DEFMETHOD (GRAPHICS-BOX :BIT-ARRAY) ()
- (GRAPHICS-SHEET-BIT-ARRAY GRAPHICS-SHEET))
-
- (DEFMETHOD (GRAPHICS-BOX :GRAPHICS-SHEET) ()
- GRAPHICS-SHEET)
-
- (DEFUN DRAWING-WIDTH (GRAPHICS-SHEET)
- ;; Returns the width of the area of a bit-array for a graphics
- ;; box. Note that this doesn't have to be = to
- ;; ARRAY-DIMENSION-N because of BITBLT's multiple of 32.
- ;; requirement
- (GRAPHICS-SHEET-DRAW-WID GRAPHICS-SHEET))
-
- (DEFUN DRAWING-HEIGHT (GRAPHICS-SHEET)
- (GRAPHICS-SHEET-DRAW-HEI GRAPHICS-SHEET))
-
- (DEFMETHOD (GRAPHICS-BOX :BIT-ARRAY-WID) ()
- (GRAPHICS-SHEET-DRAW-WID GRAPHICS-SHEET))
-
- (DEFMETHOD (GRAPHICS-BOX :BIT-ARRAY-HEI) ()
- (GRAPHICS-SHEET-DRAW-HEI GRAPHICS-SHEET))
-
- (DEFMETHOD (GRAPHICS-BOX :GRAPHICS-SHEET-SIZE) ()
- (VALUES (GRAPHICS-SHEET-DRAW-WID GRAPHICS-SHEET)
- (GRAPHICS-SHEET-DRAW-HEI GRAPHICS-SHEET)))
-
- (DEFMETHOD (GRAPHICS-BOX :DRAW-MODE) ()
- (GRAPHICS-SHEET-DRAW-MODE GRAPHICS-SHEET))
-
- (DEFMETHOD (GRAPHICS-BOX :SET-DRAW-MODE) (NEW-MODE)
- (SETF (GRAPHICS-SHEET-DRAW-MODE GRAPHICS-SHEET) NEW-MODE))
-
- (DEFMETHOD (GRAPHICS-BOX :CLEAR-BOX) ()
- (DOLIST (SCREEN-BOX (GET-VISIBLE-SCREEN-OBJS SELF))
- (UNLESS (EQ ':SHRUNK (TELL SCREEN-BOX :DISPLAY-STYLE))
- (DRAWING-ON-TURTLE-SLATE SCREEN-BOX
- (TV:%DRAW-RECTANGLE (GRAPHICS-SHEET-DRAW-WID GRAPHICS-SHEET)
- (GRAPHICS-SHEET-DRAW-HEI GRAPHICS-SHEET)
- (SCALE-X 0)
- (SCALE-Y 0)
- TV:ALU-ANDCA
- %DRAWING-ARRAY))))
- (TV:%DRAW-RECTANGLE (GRAPHICS-SHEET-DRAW-WID GRAPHICS-SHEET)
- (GRAPHICS-SHEET-DRAW-HEI GRAPHICS-SHEET)
- 0
- 0
- TV:ALU-ANDCA
- (GRAPHICS-SHEET-BIT-ARRAY GRAPHICS-SHEET)))
-
- (DEFMETHOD (GRAPHICS-BOX :ERASE-FROM-SCREEN) ()
- (DRAWING-ON-WINDOW (*BOXER-PANE*)
- (DOLIST (SCREEN-BOX (GET-VISIBLE-SCREEN-OBJS SELF))
- (UNLESS (EQ ':SHRUNK (TELL SCREEN-BOX :DISPLAY-STYLE))
- (WITH-TURTLE-SLATE-ORIGINS SCREEN-BOX
- (TV:%DRAW-RECTANGLE
- (GRAPHICS-SHEET-DRAW-WID GRAPHICS-SHEET)
- (GRAPHICS-SHEET-DRAW-HEI GRAPHICS-SHEET)
- %ORIGIN-X-OFFSET
- %ORIGIN-Y-OFFSET
- TV:ALU-ANDCA
- %DRAWING-WINDOW))))))
-
- (DEFMETHOD (GRAPHICS-BOX :CLEARSCREEN) ()
- (TELL SELF :CLEAR-BOX)
- (DOLIST (TURTLE (GRAPHICS-SHEET-OBJECT-LIST GRAPHICS-SHEET))
- (IF (TELL TURTLE :SHOWN-P)
- (TELL TURTLE :DRAW))))
-
- (DEFMETHOD (GRAPHICS-BOX :COPY) ()
- (LET ((NEW-BOX (MAKE-INITIALIZED-GRAPHICS-BOX ':FIXED-WID (DRAWING-WIDTH GRAPHICS-SHEET)
- ':FIXED-HEI (DRAWING-HEIGHT GRAPHICS-SHEET)))
- (BOX-STREAM (MAKE-BOX-STREAM SELF)))
- (TELL NEW-BOX :SET-CONTENTS-FROM-STREAM BOX-STREAM T)
- (WHEN (NOT-NULL PORTS)
- (PUSH (CONS SELF NEW-BOX) .LINK-TARGET-ALIST.))
- (BITBLT TV:ALU-SETA (DRAWING-WIDTH GRAPHICS-SHEET) (DRAWING-HEIGHT GRAPHICS-SHEET)
- (GRAPHICS-SHEET-BIT-ARRAY GRAPHICS-SHEET) 0 0
- (TELL NEW-BOX :BIT-ARRAY) 0 0)
- (tell new-box :export-all-variables)
- NEW-BOX))
-
- (DEFMETHOD (GRAPHICS-BOX :COMPLEMENT) ()
- (TV:%DRAW-RECTANGLE (GRAPHICS-SHEET-DRAW-WID GRAPHICS-SHEET)
- (GRAPHICS-SHEET-DRAW-HEI GRAPHICS-SHEET)
- 0
- 0
- TV:ALU-XOR
- (GRAPHICS-SHEET-BIT-ARRAY GRAPHICS-SHEET))
- (TELL SELF :MODIFIED))
-
- ;;;ED -- I've never used these and don't know if they work
- (DEFMETHOD (GRAPHICS-BOX :FILL-FROM-GRAPHICS-BOX) (FROM-BOX)
- (LET* ((FROM-SHEET (TELL FROM-BOX :GRAPHICS-SHEET))
- (FROM-WID (GRAPHICS-SHEET-DRAW-WID FROM-SHEET));need these values if we want to erase
- (FROM-HEI (GRAPHICS-SHEET-DRAW-HEI FROM-SHEET));unused space in the destination
- (TO-WID (GRAPHICS-SHEET-DRAW-WID GRAPHICS-SHEET))
- (TO-HEI (GRAPHICS-SHEET-DRAW-HEI GRAPHICS-SHEET)))
- FROM-WID FROM-HEI ;bound but never used
- (BITBLT TV:ALU-SETA (MIN FROM-WID TO-WID) (MIN TO-HEI FROM-HEI)
- (GRAPHICS-SHEET-BIT-ARRAY FROM-SHEET)
- 0 0 (GRAPHICS-SHEET-BIT-ARRAY GRAPHICS-SHEET) 0 0))
- (TELL SELF :MODIFIED))
-
- (DEFMETHOD (GRAPHICS-BOX :PLACE-STAMP-WITH-CLIPPING) (FROM-BOX X Y &OPTIONAL(ALU TV:ALU-SETA))
- (LET* ((FROM-SHEET (TELL FROM-BOX :GRAPHICS-SHEET))
- (FROM-WID (GRAPHICS-SHEET-DRAW-WID FROM-SHEET));need these values if we want to erase
- (FROM-HEI (GRAPHICS-SHEET-DRAW-HEI FROM-SHEET));unused space in the destination
- (TO-WID (GRAPHICS-SHEET-DRAW-WID GRAPHICS-SHEET))
- (TO-HEI (GRAPHICS-SHEET-DRAW-HEI GRAPHICS-SHEET)))
- (BITBLT ALU (MIN FROM-WID (- TO-WID X)) (MIN FROM-HEI (- TO-HEI Y))
- (GRAPHICS-SHEET-BIT-ARRAY FROM-SHEET)
- 0 0 (GRAPHICS-SHEET-BIT-ARRAY GRAPHICS-SHEET) X Y))
- (TELL SELF :MODIFIED))
-
- (DEFUN MAKE-GRAPHICS-BOX (&OPTIONAL (WID *DEFAULT-GRAPHICS-BOX-WID*)
- (HEI *DEFAULT-GRAPHICS-BOX-HEI*))
- (LET ((GB (MAKE-INITIALIZED-GRAPHICS-BOX ':FIXED-WID WID ':FIXED-HEI HEI)))
- GB))
-
- ;;; low level drawing utilities
-
- ;;Following functions divide a floating point coordinate
- ;;position into a "screen" [integer multiple of screen size] and
- ;;fraction of screen from the left or bottom edge. NOTE that
- ;;ALL these functions are meant to operate on ARRAY coords
-
- ;;; drawing defs
-
- (DEFVAR %BIT-ARRAY NIL
- "The bit-array of the graphics-box being operated on")
-
- (DEFVAR %DRAWING-WIDTH NIL
- "The width of the bit-array of the graphics box in which we are allowed to draw")
-
- (DEFVAR %DRAWING-HEIGHT NIL
- "The height of the bit-array of the graphics box in which we are allowed to draw")
-
- (DEFVAR %GRAPHICS-BOX NIL
- "The graphics box which is being operated on.")
-
- (DEFVAR %DRAW-MODE NIL
- "Draw-mode of the graphics box in which we are allowed to draw")
-
- (DEFMACRO WITH-GRAPHICS-VARS-BOUND (TO-BOX &BODY BODY)
- "This macro sets up an environment where commonly used parameters of the graphics box are bound. "
- `(LET* ((GR-SHEET (TELL ,TO-BOX :GRAPHICS-SHEET))
- (%BIT-ARRAY (GRAPHICS-SHEET-BIT-ARRAY GR-SHEET))
- (%DRAWING-WIDTH (1- (GRAPHICS-SHEET-DRAW-WID GR-SHEET)))
- (%DRAWING-HEIGHT (1- (GRAPHICS-SHEET-DRAW-HEI GR-SHEET)))
- (%GRAPHICS-BOX ,TO-BOX)
- (%DRAW-MODE (GRAPHICS-SHEET-DRAW-MODE GR-SHEET)))
- (PROGN . ,BODY)))
-
- ;; Here is the line drawing stuff
-
- ;;; This is the highest level drawing command.
-
- (DEFUN CK-MODE-DRAW-LINE (FROM-X FROM-Y TO-X TO-Y &OPTIONAL (ALU TV:ALU-XOR))
- (IF (EQ %DRAW-MODE ':WRAP)
- (DRAW-WRAP-LINE FROM-X FROM-Y TO-X TO-Y ALU)
- (DRAW-WINDOW-LINE FROM-X FROM-Y TO-X TO-Y ALU)))
-
- (DEFSUBST OUT-OF-RANGE? (X0 Y0 X1 Y1)
- (OR (AND (< X0 0) (< X1 0))
- (AND (> X0 %DRAWING-WIDTH) (> X1 %DRAWING-WIDTH))
- (AND (< Y1 0) (< Y0 0))
- (AND (> Y0 %DRAWING-HEIGHT) (> Y1 %DRAWING-HEIGHT))))
-
- (DEFUN DRAW-WINDOW-LINE (X0 Y0 X1 Y1 ALU)
- (UNLESS (OUT-OF-RANGE? X0 Y0 X1 Y1)
- (DRAW-VECTOR-WITH-CLIPPING X0 Y0 X1 Y1 ALU)))
-
- (DEFSUBST WINDOW-CLIP-X (X-POS)
- (MIN (1- %DRAWING-WIDTH) (MAX X-POS 0)))
-
- (DEFSUBST WINDOW-CLIP-Y (Y-POS)
- (MIN (1- %DRAWING-HEIGHT) (MAX Y-POS 0)))
-
- ;;; This works in some tricky places where gregor's routine doesn't
- (DEFUN CALC-CLIPPED-VECTOR (X0 Y0 X1 Y1)
- (COND ((AND (POINT-IN-ARRAY? X0 Y0) (POINT-IN-ARRAY? X1 Y1))
- (VALUES X0 Y0 X1 Y1))
- ((= X0 X1)
- (VALUES X0 (WINDOW-CLIP-Y Y0) X1 (WINDOW-CLIP-Y Y1)))
- ((= Y0 Y1)
- (VALUES (WINDOW-CLIP-X X0) Y0 (WINDOW-CLIP-X X1) Y0))
- (T
- (LET ((X-LENGTH (FLOAT (- X1 X0))) (Y-LENGTH (FLOAT (- Y1 Y0)))
- (CLIPPED-X0 (WINDOW-CLIP-X X0))
- (CLIPPED-Y0 (WINDOW-CLIP-Y Y0))
- (CLIPPED-X1 (WINDOW-CLIP-X X1))
- (CLIPPED-Y1 (WINDOW-CLIP-Y Y1)))
- (IF (< (// (FLOAT (- CLIPPED-X1 X0))
- X-LENGTH)
- (// (FLOAT (- CLIPPED-Y1 Y0))
- Y-LENGTH))
- (SETQ CLIPPED-Y1 (+ Y0 (* (- CLIPPED-X1 X0)
- (// Y-LENGTH X-LENGTH))))
- (SETQ CLIPPED-X1 (+ X0 (* (- CLIPPED-Y1 Y0)
- (// X-LENGTH Y-LENGTH)))))
- (IF (< (// (FLOAT (- X1 CLIPPED-X0))
- X-LENGTH)
- (// (FLOAT (- Y1 CLIPPED-Y0))
- Y-LENGTH))
- (SETQ CLIPPED-Y0 (- Y1 (* (- X1 CLIPPED-X0)
- (// Y-LENGTH X-LENGTH))))
- (SETQ CLIPPED-X0 (- X1 (* (- Y1 CLIPPED-Y0)
- (// X-LENGTH Y-LENGTH)))))
- (WHEN (POINT-IN-ARRAY? (FIXR CLIPPED-X0) (FIXR CLIPPED-Y0))
- (VALUES (FIXR CLIPPED-X0) (FIXR CLIPPED-Y0)
- (FIXR CLIPPED-X1) (FIXR CLIPPED-Y1)))))))
-
- ;;; This function clips a vector and draws it both to the
- ;;; graphics-box bit array and to each visible screen object.
-
- (DEFUN DRAW-VECTOR-WITH-CLIPPING (X0 Y0 X1 Y1 ALU)
- (MULTIPLE-VALUE-BIND (CLIPPED-X0 CLIPPED-Y0 CLIPPED-X1 CLIPPED-Y1)
- (CALC-CLIPPED-VECTOR X0 Y0 X1 Y1)
- (WHEN CLIPPED-X0
- (DRAW-VECTOR CLIPPED-X0 CLIPPED-Y0 CLIPPED-X1 CLIPPED-Y1 ALU))))
-
- ;;; The following does not check clipping --- use with care !!!
-
- (DEFUN DRAW-VECTOR (CLIPPED-X0 CLIPPED-Y0 CLIPPED-X1 CLIPPED-Y1 ALU)
- (LET ((END-POINT? (NOT (= ALU TV:ALU-XOR))))
- (WITHOUT-INTERRUPTS
- (WHEN (GRAPHICS-BOX? %GRAPHICS-BOX)
- (DOLIST (SCREEN-BOX (GET-VISIBLE-SCREEN-OBJS %GRAPHICS-BOX))
- (UNLESS (EQ ':SHRUNK (TELL SCREEN-BOX :DISPLAY-STYLE))
- (DRAWING-ON-TURTLE-SLATE SCREEN-BOX
- (SYS:%DRAW-LINE (SCALE-X CLIPPED-X0) (SCALE-Y CLIPPED-Y0)
- (SCALE-X CLIPPED-X1) (SCALE-Y CLIPPED-Y1)
- ALU END-POINT? %DRAWING-ARRAY)))))
- (SYS:%DRAW-LINE CLIPPED-X0 CLIPPED-Y0 CLIPPED-X1 CLIPPED-Y1
- ALU END-POINT? %BIT-ARRAY))))
-
- (DEFUN DRAW-WRAP-LINE (FROM-X FROM-Y TO-X TO-Y &OPTIONAL (ALU TV:ALU-XOR))
- "Draws vector allowing wraparound. Arguments in ARRAY coordinates."
- (LET ((FROM-SCREEN-X (SCREEN-X FROM-X))
- (FROM-SCREEN-Y (SCREEN-Y FROM-Y))
- (TO-SCREEN-X (SCREEN-X TO-X))
- (TO-SCREEN-Y (SCREEN-Y TO-Y)))
- (LET ((FROM-FRACTION-X (SCREEN-FRACTION-X FROM-SCREEN-X FROM-X))
- (FROM-FRACTION-Y (SCREEN-FRACTION-Y FROM-SCREEN-Y FROM-Y))
- (TO-FRACTION-X (SCREEN-FRACTION-X TO-SCREEN-X TO-X))
- (TO-FRACTION-Y (SCREEN-FRACTION-Y TO-SCREEN-Y TO-Y)))
- ;;Split up into screens and fractions of screens, then hand off
- ;;to WRAP-SCREEN-VECTOR.
- (WRAP-SCREEN-VECTOR FROM-SCREEN-X FROM-FRACTION-X
- FROM-SCREEN-Y FROM-FRACTION-Y
- TO-SCREEN-X TO-FRACTION-X
- TO-SCREEN-Y TO-FRACTION-Y
- ALU))))
-
- (DEFUN SCREEN-X (WRAP-X)
- (IF (MINUSP WRAP-X)
- (1- (FIX (// WRAP-X %DRAWING-WIDTH))) ;PERHAPS 1+
- (FIX (// WRAP-X %DRAWING-WIDTH))))
-
- (DEFUN SCREEN-Y (WRAP-Y)
- (IF (MINUSP WRAP-Y)
- (1- (FIX (// WRAP-Y %DRAWING-HEIGHT)))
- (FIX (// WRAP-Y %DRAWING-HEIGHT))))
-
- (DEFUN SCREEN-FRACTION-X (SCREEN-WIDS WRAP-X)
- (// (FLOAT (- WRAP-X (* SCREEN-WIDS %DRAWING-WIDTH)))
- %DRAWING-WIDTH))
-
- (DEFUN SCREEN-FRACTION-Y (SCREEN-HEIS WRAP-Y)
- (// (FLOAT (- WRAP-Y (* SCREEN-HEIS %DRAWING-HEIGHT)))
- %DRAWING-HEIGHT))
-
- (DEFUN WRAP-SCREEN-VECTOR (FROM-SCREEN-X FROM-FRACTION-X FROM-SCREEN-Y FROM-FRACTION-Y
- TO-SCREEN-X TO-FRACTION-X TO-SCREEN-Y TO-FRACTION-Y
- ALU
- &AUX TO-EDGE-X SIGN-X TO-EDGE-Y SIGN-Y
- FROM-EDGE-FRACTION TO-EDGE-FRACTION)
- (WITHOUT-INTERRUPTS
- (COND ((NOT (= FROM-SCREEN-X TO-SCREEN-X))
- ;; Vector crosses a X screen edge.
- (LET ((CHANGE-X (+ (- TO-SCREEN-X FROM-SCREEN-X)
- (- TO-FRACTION-X FROM-FRACTION-X)))
- (CHANGE-Y (+ (- TO-SCREEN-Y FROM-SCREEN-Y)
- (- TO-FRACTION-Y FROM-FRACTION-Y))))
- (IF (PLUSP CHANGE-X)
- (SETQ SIGN-X 1.
- TO-EDGE-X (- 1.0 FROM-FRACTION-X)
- FROM-EDGE-FRACTION 1.0
- TO-EDGE-FRACTION 0.0)
- (SETQ SIGN-X -1.
- TO-EDGE-X (- FROM-FRACTION-X)
- FROM-EDGE-FRACTION 0.0
- TO-EDGE-FRACTION 1.0))
- ;; compute the X and Y coordinates to split the vector at the X edge
- (LET* ((EDGE-FRACTION-Y (+ FROM-FRACTION-Y
- (* TO-EDGE-X (// CHANGE-Y CHANGE-X))))
- (EDGE-SCREEN-Y FROM-SCREEN-Y)
- (FIX-EDGE-FRACTION (FIX EDGE-FRACTION-Y)))
- (INCF EDGE-SCREEN-Y FIX-EDGE-FRACTION)
- (SETQ EDGE-FRACTION-Y (- EDGE-FRACTION-Y (FLOAT FIX-EDGE-FRACTION)))
- ;; draw a vector from the FROM point to the edge...
- (WRAP-SCREEN-VECTOR FROM-SCREEN-X FROM-FRACTION-X
- FROM-SCREEN-Y FROM-FRACTION-Y
- FROM-SCREEN-X FROM-EDGE-FRACTION
- EDGE-SCREEN-Y EDGE-FRACTION-Y
- ALU)
- ;; ...and then continue on to the TO point
- (WRAP-SCREEN-VECTOR (+ FROM-SCREEN-X SIGN-X)
- TO-EDGE-FRACTION
- EDGE-SCREEN-Y EDGE-FRACTION-Y
- TO-SCREEN-X TO-FRACTION-X
- TO-SCREEN-Y TO-FRACTION-Y
- ALU))))
- ((NOT (= FROM-SCREEN-Y TO-SCREEN-Y))
- ;; Vector crosses a Y screen edge
- (LET ((CHANGE-X (+ (- TO-SCREEN-X FROM-SCREEN-X)
- (- TO-FRACTION-X FROM-FRACTION-X)))
- (CHANGE-Y (+ (- TO-SCREEN-Y FROM-SCREEN-Y)
- (- TO-FRACTION-Y FROM-FRACTION-Y))))
- (IF (PLUSP CHANGE-Y)
- (SETQ SIGN-Y 1.
- TO-EDGE-Y (- 1.0 FROM-FRACTION-Y)
- FROM-EDGE-FRACTION 1.0
- TO-EDGE-FRACTION 0.0)
- (SETQ SIGN-Y -1.
- TO-EDGE-Y (- FROM-FRACTION-Y)
- FROM-EDGE-FRACTION 0.0
- TO-EDGE-FRACTION 1.0))
- ;; compute the X and Y coordinates to split the vector at the Y edge
- (LET* ((EDGE-FRACTION-X (+ FROM-FRACTION-X
- (* TO-EDGE-Y (// CHANGE-X CHANGE-Y))))
- (EDGE-SCREEN-X FROM-SCREEN-X)
- (FIX-EDGE-FRACTION (FIX EDGE-FRACTION-X)))
- (INCF EDGE-SCREEN-X FIX-EDGE-FRACTION)
- (SETQ EDGE-FRACTION-X (- EDGE-FRACTION-X (FLOAT FIX-EDGE-FRACTION)))
- ;; draw a vector from the FROM point to the edge...
- (WRAP-SCREEN-VECTOR FROM-SCREEN-X FROM-FRACTION-X
- FROM-SCREEN-Y FROM-FRACTION-Y
- EDGE-SCREEN-X EDGE-FRACTION-X
- FROM-SCREEN-Y FROM-EDGE-FRACTION
- ALU)
- ;; ...and then continue on to the TO point
- (WRAP-SCREEN-VECTOR EDGE-SCREEN-X EDGE-FRACTION-X
- (+ FROM-SCREEN-Y SIGN-Y) TO-EDGE-FRACTION
- TO-SCREEN-X TO-FRACTION-X
- TO-SCREEN-Y TO-FRACTION-Y
- ALU))))
- (T ;looks like its cool to draw the line as is
- (LET ((X0 (FIXR (* %DRAWING-WIDTH FROM-FRACTION-X)))
- (Y0 (FIXR (* %DRAWING-HEIGHT FROM-FRACTION-Y)))
- (X1 (FIXR (* %DRAWING-WIDTH TO-FRACTION-X)))
- (Y1 (FIXR (* %DRAWING-HEIGHT TO-FRACTION-Y))))
- (DRAW-VECTOR X0 Y0 X1 Y1 ALU))))))
-
- ;;; This function draw a list of vectors and strings. The below
- ;;; is what draws a turtle's shape given its vector list
- ;;; repesentation. I think the iteration construct could be
- ;;; written more cleanly.
-
- (DEFCONST *DEFAULT-GRAPHICS-FONT* FONTS:TVFONT
- "The font used for drawing in graphics boxes")
-
- (DEFCONST *FONT-WIDTH* (FONT-CHAR-WIDTH *DEFAULT-GRAPHICS-FONT*))
-
- (DEFCONST *FONT-HEIGHT* (FONT-CHAR-HEIGHT *DEFAULT-GRAPHICS-FONT*))
-
- (DEFUN DRAW-VECTOR-LIST (V-LIST SIZE START-X START-Y HEADING &OPTIONAL (ALU TV:ALU-XOR))
- (D-V-L-ITER V-LIST START-X START-Y (* SIZE (COSD HEADING)) (* SIZE (SIND HEADING)) 'D ALU))
-
- (DEFUN D-V-L-ITER (V-LIST START-X START-Y COS-HEAD SIN-HEAD PEN ALU)
- (DO ()
- ((NULL V-LIST))
- (COND
- ((MEMQ (FIRST V-LIST) '(UP :UP :ERASE ERASE))
- (SETQ PEN 'U V-LIST (CDR V-LIST)))
- ((MEMQ (FIRST V-LIST) '(DOWN XOR :DOWN :XOR))
- (SETQ PEN 'D V-LIST (CDR V-LIST)))
- ((STRINGP (FIRST V-LIST))
- (WHEN (EQ PEN 'D)
- (LET ((XPOS (FIXR (+ 3. START-X))) (YPOS (FIXR (1+ START-Y))))
- (DRAW-STRING-TO-GBOX (FIRST V-LIST) XPOS YPOS)))
- (SETQ V-LIST (CDR V-LIST)))
- ;; compatibility with an old format. remove this soon 6/30/85
- ((LISTP (FIRST V-LIST))
- (WHEN (EQ PEN 'D)
- (LET ((XPOS (FIXR (+ 3. START-X))) (YPOS (FIXR (1+ START-Y))))
- (DRAW-STRING-TO-GBOX (CAR (FIRST V-LIST)) XPOS YPOS)))
- (SETQ V-LIST (CDR V-LIST)))
- (T
- (LET ((END-X (+ START-X
- (* (FIRST V-LIST) COS-HEAD)
- (* (SECOND V-LIST) (- SIN-HEAD))))
- (END-Y (+ START-Y
- (* (+ (* (FIRST V-LIST) SIN-HEAD)
- (* (SECOND V-LIST) COS-HEAD))
- *SCRUNCH-FACTOR*))))
- (WHEN (EQ PEN 'D)
- (DRAW-WINDOW-LINE (FIXR START-X) (FIXR START-Y)
- (FIXR END-X) (FIXR END-Y) ALU))
- (SETQ START-X END-X START-Y END-Y V-LIST (CDDR V-LIST)))))))
-
- ;;; drawing chars on graphics windows
-
- (DEFSUBST CLIP-STRING (STRING X-POS)
- (LET ((NEW-LENGTH (MIN (STRING-LENGTH STRING)
- (FIXR (// (- %DRAWING-WIDTH X-POS) *FONT-WIDTH*)))))
- (SUBSTRING STRING 0 NEW-LENGTH)))
-
- ;;; no CR's
- (DEFUN DRAW-SIMPLE-STRING-TO-GBOX (STRING X-POS Y-POS ALU)
- (IF (NOT (AND (POINT-IN-ARRAY? X-POS Y-POS)
- (POINT-IN-ARRAY? X-POS (+ Y-POS *FONT-HEIGHT*))))
- NIL ;;; can not print string at all
- (LET* ((CLIPPED-STRING (CLIP-STRING STRING X-POS))
- (CHAR-LIST (MAPCAR (FUNCTION CHARACTER)
- (LISTARRAY CLIPPED-STRING))))
- (WITHOUT-INTERRUPTS
- ;;; draw to the bit array
- (LET ((CURSOR X-POS))
- (DOLIST (CHAR CHAR-LIST)
- (SYS:%DRAW-CHAR *DEFAULT-GRAPHICS-FONT*
- CHAR CURSOR Y-POS ALU %BIT-ARRAY)
- (SETQ CURSOR (+ CURSOR *FONT-WIDTH*))))
- ;;; draw to each visible screen object
- (WHEN (GRAPHICS-BOX? %GRAPHICS-BOX)
- (DRAWING-ON-WINDOW (*BOXER-PANE*)
- (DOLIST (SCREEN-BOX (GET-VISIBLE-SCREEN-OBJS %GRAPHICS-BOX))
- (UNLESS (EQ ':SHRUNK (TELL SCREEN-BOX :DISPLAY-STYLE))
- (WITH-TURTLE-SLATE-ORIGINS SCREEN-BOX ;
- (LET ((CURSOR-X (+ X-POS %ORIGIN-X-OFFSET))
- (CURSOR-Y (+ Y-POS %ORIGIN-Y-OFFSET)))
- (DOLIST (CHAR CHAR-LIST)
- (SYS:%DRAW-CHAR *DEFAULT-GRAPHICS-FONT*
- CHAR CURSOR-X CURSOR-Y ALU %DRAWING-ARRAY)
- (SETQ CURSOR-X (+ CURSOR-X *FONT-WIDTH*)))
- )))))))
- CLIPPED-STRING)))
-
- ;;; CR's are allowed
- (DEFUN DRAW-STRING-TO-GBOX (STRING X-POS START-Y-POS &OPTIONAL (ALU TV:ALU-XOR))
- (LOOP WITH START = 0
- WITH Y-POS = START-Y-POS
- FOR INDEX FROM 0 TO (1- (STRING-LENGTH STRING))
- FOR CHA = (AREF STRING INDEX)
- WHEN (OR (CHAR= CHA #\CR) (CHAR= CHA #\LINE))
- DO (DRAW-SIMPLE-STRING-TO-GBOX (NSUBSTRING STRING START INDEX) X-POS Y-POS ALU)
- (SETQ START (1+ INDEX)
- Y-POS (+ Y-POS *FONT-HEIGHT*))
- FINALLY
- (DRAW-SIMPLE-STRING-TO-GBOX (NSUBSTRING STRING START INDEX) X-POS Y-POS ALU)))
-