diff --git a/collects/htdp/matrix-client.ss b/collects/htdp/Test/matrix-client.ss similarity index 100% rename from collects/htdp/matrix-client.ss rename to collects/htdp/Test/matrix-client.ss diff --git a/collects/htdp/matrix-invisible.ss b/collects/htdp/matrix-invisible.ss index dab6a613e1..7cd7162690 100644 --- a/collects/htdp/matrix-invisible.ss +++ b/collects/htdp/matrix-invisible.ss @@ -8,6 +8,7 @@ (unit (import) (export matrix-render^) (define-struct invisible (matrix)) + (define visible? invisible?) (define make-visible make-invisible) (define visible-matrix invisible-matrix))) @@ -20,4 +21,4 @@ (define-values/invoke-unit invisible-matrix@ (import) (export matrix^)) -(provide-signature-elements matrix^) \ No newline at end of file +(provide-signature-elements matrix^) diff --git a/collects/htdp/matrix-render.ss b/collects/htdp/matrix-render.ss index f8f6883adc..85e0a499e4 100644 --- a/collects/htdp/matrix-render.ss +++ b/collects/htdp/matrix-render.ss @@ -3,4 +3,6 @@ ;; type: [VM X] make-visible ;; [Matrix X] -> [VM X] -visible-matrix ;; [VM X] -> [Matrix M] \ No newline at end of file +visible-matrix ;; [VM X] -> [Matrix M] + +visible? ;; Any -> Boolean diff --git a/collects/htdp/matrix-unit.ss b/collects/htdp/matrix-unit.ss index b7416d93ab..8984cc724d 100644 --- a/collects/htdp/matrix-unit.ss +++ b/collects/htdp/matrix-unit.ss @@ -1,4 +1,4 @@ -#lang scheme/unit +#lang scheme (require (lib "matrix-sig.ss" "htdp") (lib "matrix-render.ss" "htdp") @@ -8,27 +8,18 @@ (lib "pconvert.ss") (lib "pretty.ss")) -(import matrix-render^) -(export matrix^) - - -(define (matrix-mixin% s%) - (class s% +(printf "loading module matrix-unit @ bmatrix\n") +;; [Matrix X] = [BST X] +(define bmatrix% + (class object% (init-field n m mat) + (define/public (get-n) n) + (define/public (get-m) m) + (define/public (get-mat) mat) ;; [InnerMatrix X] = Nat x Nat x [vectorof X] ;; s.t. (= (* n m)(vector-length vector)) (super-new))) -;; [Matrix X] = [BST X] -(define bmatrix% (matrix-mixin% object%)) - -(define (create-matrix n m mat) - (new bmatrix% [n n] [m m] [mat mat])) - -(define matrix-get-mat (class-field-accessor bmatrix% mat)) -(define matrix-get-n (class-field-accessor bmatrix% n)) -(define matrix-get-m (class-field-accessor bmatrix% m)) - (define-struct imatrix (left i j info right) #:transparent) (define (set-imatrix-left n x) (make-imatrix x (imatrix-i n) (imatrix-j n) (imatrix-info n) (imatrix-right n))) @@ -37,6 +28,20 @@ (define (set-imatrix-info n x) (make-imatrix (imatrix-left n) (imatrix-i n) (imatrix-j n) x (imatrix-right n))) +(provide matrix@) + +(define matrix@ + (unit + (import matrix-render^) + (export matrix^) + +(define (create-matrix n m mat) + (new bmatrix% [n n] [m m] [mat mat])) + +(define (matrix-get-mat bm) (send bm get-mat)) +(define (matrix-get-n bm) (send bm get-n)) +(define (matrix-get-m bm) (send bm get-m)) + ;; [BST X] = [InnerMatrix X] | (make-imatrix [BST X] Nat Nat X [BST X]) ;; Nat Nat Nat Nat -> Boolean @@ -229,7 +234,11 @@ ;; Symbol [Matrix X] Nat Nat ->* [Vectorof X] Nat Nat ;; contract checking for teaching languages; compute properties of matrix (define (check-matrix tag M* i j) - (define M (if (matrix? M*) M* (visible-matrix M*))) + (define M (cond + [(matrix? M*) M*] + [(visible? M*) (printf "dereferencing ... \n") (visible-matrix M*)] + [else (error 'check-matrix "something is wrong: ~e ~e~e\n" + M* (visible? M*) (send M* get-M))])) (check-arg tag (matrix? M) 'matrix "first" M) (check-arg tag (natural? i) 'Nat "second" i) (check-arg tag (natural? j) 'Nat "third" j) @@ -253,3 +262,4 @@ [(= n 2) "nd"] [(> n 3) "th"] [else (error 'th "can't happen")])) +)) diff --git a/collects/htdp/matrix.ss b/collects/htdp/matrix.ss index a968fc0b16..65e4d45b71 100644 --- a/collects/htdp/matrix.ss +++ b/collects/htdp/matrix.ss @@ -11,191 +11,202 @@ (lib "mred.ss" "mred") (lib "cache-image-snip.ss" "mrlib")) -(define matrix-snip-class 'missing) -(define matrix-snip-class% 'missing) - -;; --------------------------------------------------------------------------- (provide (rename-out (matrix-snip-class snip-class)) matrix-snip-class%) +;; --------------------------------------------------------------------------- +;(define matrix-snip-class 'missing) +;(define matrix-snip-class% 'missing) + +(define (v-m VM) (send VM get-M)) +(define (v? VM) (is-a? VM visible-matrix%)) + +(printf "loading module matrix.ss @ visible-matrix\n") +;; representing a matrix that renders itself as an image, as in image.ss +(define visible-matrix% + (class cache-image-snip% + (inherit set-snipclass get-argb) + (inherit-field dc-proc argb-proc width height argb px py) + + (init-field M) + (define/public (get-M) M) + + ;; create a matrix from this instance + (define/override (copy) + (new visible-matrix% + (M M) + (width width) (height height) (px px) (py py) (argb argb) + (dc-proc dc-proc) + (argb-proc argb-proc))) + + (define/override (write f) + (let ([str (string->bytes/utf-8 + (format "~s" + (list (matrix->rectangle M) + (list (argb-vector (get-argb)) + width + px + py))))]) + (send f put str))) + + (super-new) + (set-snipclass matrix-snip-class))) + +;; the snip class for matricies +(define matrix-snip-class% + (class cache-image-snip-class% + (super-new) + (define/override (read f) + (data->snip (read-from-string (send f get-bytes) (lambda () #f)))) + (define/override (data->snip data) + (define _ (unless data (error 'read "in matrix-snip-class% failed"))) + (define new-cache-image-snip (super data->snip (cadr data))) + (define-values (w h) (send new-cache-image-snip get-size)) + (define M (rectangle->matrix (car data))) + ;; .. but we need to produce a visible-matrix% instead + M + #; + (new visible-matrix% + (M M) + (dc-proc (send new-cache-image-snip get-dc-proc)) + (argb-proc (send new-cache-image-snip get-argb-proc)) + (width w) + (height h) + (argb (get-argb new-cache-image-snip)) + (px (get-px new-cache-image-snip)) + (py (get-py new-cache-image-snip)))))) +(define get-argb (class-field-accessor cache-image-snip% argb)) +(define get-px (class-field-accessor cache-image-snip% px)) +(define get-py (class-field-accessor cache-image-snip% py)) + +;; setting up the 'snip class' +(define matrix-snip-class (new matrix-snip-class%)) +(send matrix-snip-class set-version 1) +(send matrix-snip-class set-classname (format "~s" `(lib "matrix.ss" "htdp"))) +(send the-drscheme-snip-class #;(get-the-snip-class-list) add matrix-snip-class) + +;; --------------------------------------------------------------------------- + (define render@ - (unit (import matrix^) - (export matrix-render^) - - ;; representing a matrix that renders itself as an image, as in image.ss - (define visible-matrix% - (class cache-image-snip% - (inherit set-snipclass get-argb) - (init-field M) - (inherit-field dc-proc argb-proc width height argb px py) - - ;; create a matrix from this instance - (define/override (copy) - (new visible-matrix% - (M M) - (width width) (height height) (px px) (py py) (argb argb) - (dc-proc dc-proc) - (argb-proc argb-proc))) - - (define/override (write f) - (let ([str (string->bytes/utf-8 - (format "~s" - (list (matrix->rectangle M) - (list (argb-vector (get-argb)) - width - px - py))))]) - (send f put str))) - - (super-new) - (set-snipclass matrix-snip-class))) - - (define visible-matrix (class-field-accessor visible-matrix% M)) - - ;; the snip class for matricies - (define matrix-snip-class% - (class cache-image-snip-class% - (super-new) - (define/override (read f) - (data->snip (read-from-string (send f get-bytes) (lambda () #f)))) - (define/override (data->snip data) - (define _ (unless data (error 'read "in matrix-snip-class% failed"))) - (define new-cache-image-snip (super data->snip (cadr data))) - (define-values (w h) (send new-cache-image-snip get-size)) - (define M (rectangle->matrix (car data))) - ;; .. but we need to produce a visible-matrix% instead - (new visible-matrix% - (M M) - (dc-proc (send new-cache-image-snip get-dc-proc)) - (argb-proc (send new-cache-image-snip get-argb-proc)) - (width w) - (height h) - (argb (get-argb new-cache-image-snip)) - (px (get-px new-cache-image-snip)) - (py (get-py new-cache-image-snip)))))) - (define get-argb (class-field-accessor cache-image-snip% argb)) - (define get-px (class-field-accessor cache-image-snip% px)) - (define get-py (class-field-accessor cache-image-snip% py)) - - ;; setting up the 'snip class' - (define matrix-snip-class (new matrix-snip-class%)) - (send matrix-snip-class set-version 1) - (send matrix-snip-class set-classname (format "~s" `(lib "matrix.ss" "htdp"))) - (send the-drscheme-snip-class #;(get-the-snip-class-list) add matrix-snip-class) - - ;; the graphical stuff follows .. it is code based on image.ss - ;; Matrix -> VisibleMatrix - (define (make-visible M) - (define S (matrix-render M)) - (define indent 3) - (define xspan 3) - (define-values (row-heights col-widths) (text-sizes S)) - (define th ;; total height of matrix: 2 lines plus the text height - (+ 2 (apply + row-heights))) - (define tw ;; total width of matrix: 2 identations, n xspans - (+ 1 (* 2 indent) (apply + col-widths) (* (length col-widths) xspan))) - ;; - (define (draw-proc mode dc dx dy) - [define old-mode (send dc get-text-mode)] - [define old-fore (send dc get-text-foreground)] - [define old-font (send dc get-font)] - (send dc set-text-mode mode) - (send dc set-text-foreground COLOR) - (send dc set-font (get-font SIZE)) - ;; --- left bracket - (send dc draw-line dx dy (+ dx indent) dy) - (send dc draw-line dx (+ dy th -1) (+ dx indent) (+ dy th -1)) - (send dc draw-line dx dy dx (+ dy th -1)) - ;; --- right bracket - (send dc draw-line (+ dx tw (- indent) -1) dy (+ dx tw -1) dy) - (send dc draw-line (+ dx tw (- indent) -1) (+ dy th -1) (+ dx tw -1) (+ dy th -1)) - (send dc draw-line (+ dx tw -1) dy (+ dx tw -1) (+ dy th -1)) - ;; --- draw all matrix cells - (draw-matrix S dc dx dy indent xspan col-widths row-heights) - (send dc set-text-mode old-mode) - (send dc set-text-foreground old-fore) - (send dc set-font old-font)) - ;; - (define (argb-proc argb dx dy) - (define (bm-color-builder dc) - (define p (send the-pen-list find-or-create-pen "black" 1 'transparent)) - (define b (send the-brush-list find-or-create-brush COLOR 'solid)) - (send dc set-pen p) - (send dc set-brush b) - (send dc draw-rectangle 0 0 tw th)) - (define bm-color (build-bitmap bm-color-builder tw th)) - (define(bm-mask-builder dc) (draw-proc 'solid dc 0 0)) - (define bm-mask (build-bitmap bm-mask-builder tw th)) - (overlay-bitmap argb dx dy bm-color bm-mask)) - (new visible-matrix% - [M M] - [width tw] [height th] [px 0] [py 0] - [dc-proc (lambda (dc dx dy) (draw-proc 'transparent dc dx dy))] - [argb-proc argb-proc])) - - ;; [Rectangle String] DC Nat Nat Nat Nat [Listof Nat] [Listof Nat] -> Void - (define (draw-matrix S dc dx dy indent xspan col-widths row-heights) - (define dx0 dx) - (for-each (lambda (row deltay) - (set! dx (+ dx0 2 indent)) - (for-each (lambda (str deltax) - (draw-centrally dc str dx dy deltax deltay) - (set! dx (+ deltax xspan dx))) - row col-widths) - (set! dy (+ 2 deltay dy))) - S row-heights)) - - ;; basic constants - (define SIZE 12) - (define COLOR (send the-color-database find-color "black")) - - ;; String Nat Nat Nat Nat -> Void - ;; draw str centrally into a (deltax x deltay) rectangle of dc - ;; whose upper-left position is (dx,dy) - (define (draw-centrally dc str dx dy deltax deltay) - (define-values (w h) (get-text-size SIZE str)) - (define dx* (+ dx (quotient (- deltax w) 2))) - (define dy* (+ dy (quotient (- deltay h) 2))) - (send dc draw-text str dx* dy*)) - - ;; [Rectangle String] ->* [Listof Nat] [Listof Nat] - ;; determine the height of each row and the width of each column - (define (text-sizes S) - (define S-sizes - (map (lambda (row) - (map (lambda (cell) - (define-values (tw th) (get-text-size SIZE cell)) - (list tw th)) - row)) - S)) - (define row-heights (map (lambda (r) (apply max (map cadr r))) S-sizes)) - (define col-widths - (let loop ([S-sizes S-sizes]) - (if (andmap null? S-sizes) - '() - (cons (apply max (map car (map car S-sizes))) - (loop (map cdr S-sizes)))))) - (values row-heights col-widths)) - - ;; --- copied from image.ss --- needs refactoring - (define (get-text-size size string) - (unless (thread-cell-ref cached-bdc-for-text-size) - (let* ([bm (make-object bitmap% 1 1)] - [dc (make-object bitmap-dc% bm)]) - (thread-cell-set! cached-bdc-for-text-size dc))) - (let ([dc (thread-cell-ref cached-bdc-for-text-size)]) - (let-values ([(w h _1 _2) (send dc get-text-extent string (get-font size))]) - (values (inexact->exact (ceiling w)) - (inexact->exact (ceiling h)))))) - - (define (get-font size) - (send the-font-list find-or-create-font size - 'default 'normal 'normal #f - (case (system-type) - [(macosx) 'partly-smoothed] - [else 'smoothed]))) - - (define cached-bdc-for-text-size (make-thread-cell #f)))) + (unit + (import matrix^) + (export matrix-render^) + (define visible? v?) + (define visible-matrix v-m) + + ;; the graphical stuff follows .. it is code based on image.ss + ;; Matrix -> VisibleMatrix + (define (make-visible M) + (define S (matrix-render M)) + (define indent 3) + (define xspan 3) + (define-values (row-heights col-widths) (text-sizes S)) + (define th ;; total height of matrix: 2 lines plus the text height + (+ 2 (apply + row-heights))) + (define tw ;; total width of matrix: 2 identations, n xspans + (+ 1 (* 2 indent) (apply + col-widths) (* (length col-widths) xspan))) + ;; + (define (draw-proc mode dc dx dy) + [define old-mode (send dc get-text-mode)] + [define old-fore (send dc get-text-foreground)] + [define old-font (send dc get-font)] + (send dc set-text-mode mode) + (send dc set-text-foreground COLOR) + (send dc set-font (get-font SIZE)) + ;; --- left bracket + (send dc draw-line dx dy (+ dx indent) dy) + (send dc draw-line dx (+ dy th -1) (+ dx indent) (+ dy th -1)) + (send dc draw-line dx dy dx (+ dy th -1)) + ;; --- right bracket + (send dc draw-line (+ dx tw (- indent) -1) dy (+ dx tw -1) dy) + (send dc draw-line (+ dx tw (- indent) -1) (+ dy th -1) (+ dx tw -1) (+ dy th -1)) + (send dc draw-line (+ dx tw -1) dy (+ dx tw -1) (+ dy th -1)) + ;; --- draw all matrix cells + (draw-matrix S dc dx dy indent xspan col-widths row-heights) + (send dc set-text-mode old-mode) + (send dc set-text-foreground old-fore) + (send dc set-font old-font)) + ;; + (define (argb-proc argb dx dy) + (define (bm-color-builder dc) + (define p (send the-pen-list find-or-create-pen "black" 1 'transparent)) + (define b (send the-brush-list find-or-create-brush COLOR 'solid)) + (send dc set-pen p) + (send dc set-brush b) + (send dc draw-rectangle 0 0 tw th)) + (define bm-color (build-bitmap bm-color-builder tw th)) + (define(bm-mask-builder dc) (draw-proc 'solid dc 0 0)) + (define bm-mask (build-bitmap bm-mask-builder tw th)) + (overlay-bitmap argb dx dy bm-color bm-mask)) + (new visible-matrix% + [M M] + [width tw] [height th] [px 0] [py 0] + [dc-proc (lambda (dc dx dy) (draw-proc 'transparent dc dx dy))] + [argb-proc argb-proc])) + + ;; [Rectangle String] DC Nat Nat Nat Nat [Listof Nat] [Listof Nat] -> Void + (define (draw-matrix S dc dx dy indent xspan col-widths row-heights) + (define dx0 dx) + (for-each (lambda (row deltay) + (set! dx (+ dx0 2 indent)) + (for-each (lambda (str deltax) + (draw-centrally dc str dx dy deltax deltay) + (set! dx (+ deltax xspan dx))) + row col-widths) + (set! dy (+ 2 deltay dy))) + S row-heights)) + + ;; basic constants + (define SIZE 12) + (define COLOR (send the-color-database find-color "black")) + + ;; String Nat Nat Nat Nat -> Void + ;; draw str centrally into a (deltax x deltay) rectangle of dc + ;; whose upper-left position is (dx,dy) + (define (draw-centrally dc str dx dy deltax deltay) + (define-values (w h) (get-text-size SIZE str)) + (define dx* (+ dx (quotient (- deltax w) 2))) + (define dy* (+ dy (quotient (- deltay h) 2))) + (send dc draw-text str dx* dy*)) + + ;; [Rectangle String] ->* [Listof Nat] [Listof Nat] + ;; determine the height of each row and the width of each column + (define (text-sizes S) + (define S-sizes + (map (lambda (row) + (map (lambda (cell) + (define-values (tw th) (get-text-size SIZE cell)) + (list tw th)) + row)) + S)) + (define row-heights (map (lambda (r) (apply max (map cadr r))) S-sizes)) + (define col-widths + (let loop ([S-sizes S-sizes]) + (if (andmap null? S-sizes) + '() + (cons (apply max (map car (map car S-sizes))) + (loop (map cdr S-sizes)))))) + (values row-heights col-widths)) + + ;; --- copied from image.ss --- needs refactoring + (define (get-text-size size string) + (unless (thread-cell-ref cached-bdc-for-text-size) + (let* ([bm (make-object bitmap% 1 1)] + [dc (make-object bitmap-dc% bm)]) + (thread-cell-set! cached-bdc-for-text-size dc))) + (let ([dc (thread-cell-ref cached-bdc-for-text-size)]) + (let-values ([(w h _1 _2) (send dc get-text-extent string (get-font size))]) + (values (inexact->exact (ceiling w)) + (inexact->exact (ceiling h)))))) + + (define (get-font size) + (send the-font-list find-or-create-font size + 'default 'normal 'normal #f + (case (system-type) + [(macosx) 'partly-smoothed] + [else 'smoothed]))) + + (define cached-bdc-for-text-size (make-thread-cell #f)))) (define invisible-matrix@ (compound-unit