From 8c9088a770fc9486458a965229c35fecb7e43805 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 13 Jan 2010 16:32:21 +0000 Subject: [PATCH] changed the overlaying functions so they default to putting the images overlay'd on their centers, not upper lefts svn: r17632 --- collects/2htdp/private/image-more.ss | 24 +-- collects/2htdp/tests/test-image.ss | 124 +++++++++++---- collects/mrlib/image-core.ss | 142 ++++++++++++------ .../teachpack/2htdp/scribblings/image-toc.ss | 31 ++-- .../teachpack/2htdp/scribblings/image.scrbl | 87 ++--------- .../2htdp/scribblings/img/10a0d35fa03.png | Bin 0 -> 2345 bytes .../2htdp/scribblings/img/11b64ab4d3.png | Bin 0 -> 742 bytes .../2htdp/scribblings/img/1404e4b2af.png | Bin 0 -> 1150 bytes .../2htdp/scribblings/img/166bb7bc683.png | Bin 2247 -> 0 bytes .../2htdp/scribblings/img/1acede17bc6.png | Bin 0 -> 1572 bytes .../2htdp/scribblings/img/1aea411192a.png | Bin 1476 -> 0 bytes .../2htdp/scribblings/img/2d1e52503d7.png | Bin 1070 -> 0 bytes .../2htdp/scribblings/img/2dd0a2a4517.png | Bin 2368 -> 0 bytes .../2htdp/scribblings/img/54a488e1a5.png | Bin 0 -> 2290 bytes .../2htdp/scribblings/img/bf08c71801.png | Bin 893 -> 0 bytes .../2htdp/scribblings/img/f7f1480d58.png | Bin 2314 -> 0 bytes .../2htdp/scribblings/img/ff11314e4e.png | Bin 0 -> 2264 bytes .../2htdp/scribblings/porting-guide.scrbl | 22 +++ 18 files changed, 247 insertions(+), 183 deletions(-) create mode 100644 collects/teachpack/2htdp/scribblings/img/10a0d35fa03.png create mode 100644 collects/teachpack/2htdp/scribblings/img/11b64ab4d3.png create mode 100644 collects/teachpack/2htdp/scribblings/img/1404e4b2af.png delete mode 100644 collects/teachpack/2htdp/scribblings/img/166bb7bc683.png create mode 100644 collects/teachpack/2htdp/scribblings/img/1acede17bc6.png delete mode 100644 collects/teachpack/2htdp/scribblings/img/1aea411192a.png delete mode 100644 collects/teachpack/2htdp/scribblings/img/2d1e52503d7.png delete mode 100644 collects/teachpack/2htdp/scribblings/img/2dd0a2a4517.png create mode 100644 collects/teachpack/2htdp/scribblings/img/54a488e1a5.png delete mode 100644 collects/teachpack/2htdp/scribblings/img/bf08c71801.png delete mode 100644 collects/teachpack/2htdp/scribblings/img/f7f1480d58.png create mode 100644 collects/teachpack/2htdp/scribblings/img/ff11314e4e.png create mode 100644 collects/teachpack/2htdp/scribblings/porting-guide.scrbl diff --git a/collects/2htdp/private/image-more.ss b/collects/2htdp/private/image-more.ss index c293956cf8..2ee20d620d 100644 --- a/collects/2htdp/private/image-more.ss +++ b/collects/2htdp/private/image-more.ss @@ -114,12 +114,12 @@ ;; places images on top of each other with their upper left corners aligned. ;; last one goes on the bottom (define/chk (overlay image image2 . image3) - (overlay/internal 'left 'top image (cons image2 image3))) + (overlay/internal 'middle 'middle image (cons image2 image3))) ;; underlay : image image image ... -> image (define (underlay image image2 . image3) (let ([imgs (reverse (list* image image2 image3))]) - (overlay/internal 'left 'top (car imgs) (cdr imgs)))) + (overlay/internal 'middle 'middle (car imgs) (cdr imgs)))) ;; overlay/align : string string image image image ... -> image ;; the first string has to be one of "center" "middle" "left" or "right" (or symbols) @@ -204,7 +204,7 @@ ;; beside : image image image ... -> image ;; places images in a single horizontal row, top aligned (define/chk (beside image1 image2 . image3) - (beside/internal 'top image1 (cons image2 image3))) + (beside/internal 'middle image1 (cons image2 image3))) ;; beside/align : string image image image ... -> image ;; places images in a horizontal row where the vertical alignment is @@ -233,7 +233,7 @@ ;; above : image image image ... -> image ;; places images in a single vertical row, left aligned (define/chk (above image1 image2 . image3) - (above/internal 'left image1 (cons image2 image3))) + (above/internal 'middle image1 (cons image2 image3))) ;; beside/align : string image image image ... -> image ;; places images in a horizontal row where the vertical alignment is @@ -457,22 +457,8 @@ (+ r dx) (+ b dy))))])) -;; points->ltrb : (cons point (listof points)) -> (values number number number number) (define (points->ltrb points) - (let* ([fx (point-x (car points))] - [fy (point-y (car points))] - [left fx] - [top fy] - [right fx] - [bottom fy]) - (for-each (λ (point) - (let ([new-x (point-x point)] - [new-y (point-y point)]) - (set! left (min new-x left)) - (set! top (min new-y top)) - (set! right (max new-x right)) - (set! bottom (max new-y bottom)))) - (cdr points)) + (let-values ([(left top right bottom) (points->ltrb-values points)]) (make-ltrb left top right bottom))) (define (np-atomic-bb atomic-shape) diff --git a/collects/2htdp/tests/test-image.ss b/collects/2htdp/tests/test-image.ss index e153b28abb..378fa0199c 100644 --- a/collects/2htdp/tests/test-image.ss +++ b/collects/2htdp/tests/test-image.ss @@ -15,7 +15,7 @@ (define t (new text%)) (define f (new frame% [label ""] [width 600] [height 400])) (define ec (new editor-canvas% [parent f] [editor t])) -(for ((i (in-list images))) (send t insert i)) +(for ((i (in-list images))) (send t insert i) (send t insert " ")) (send f show #t) |# @@ -233,6 +233,47 @@ => #t) + +(let ([size 10]) + (test (add-line + (add-line + (add-line + (add-line + (rectangle size size 'solid 'white) + 0 0 0 size 'black) + 0 size size size 'black) + size size size 0 'black) + size 0 0 0 'black) + => + (overlay (rectangle size size 'outline 'black) + (rectangle size size 'solid 'white))) + + (test (add-line + (add-line + (add-line + (add-line + (rectangle size size 'solid 'white) + 0 0 size 0 'black) + size 0 size size 'black) + size size 0 size 'black) + 0 size 0 0 'black) + => + (overlay (rectangle size size 'outline 'black) + (rectangle size size 'solid 'white))) + + (test (add-line + (add-line + (add-line + (add-line + (rectangle size size 'solid 'white) + 0 0 size 0 'black) + 0 0 0 size 'black) + 0 size size size 'black) + size 0 size size 'black) + => + (overlay (rectangle size size 'outline 'black) + (rectangle size size 'solid 'white)))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; testing overlays @@ -243,7 +284,7 @@ => (make-image (make-overlay - (make-translate 0 0 (image-shape (ellipse 100 100 'solid 'blue))) + (make-translate 10 10 (image-shape (ellipse 100 100 'solid 'blue))) (make-translate 0 0 (image-shape (ellipse 120 120 'solid 'red)))) (make-bb 120 120 @@ -251,7 +292,7 @@ #f)) (test (overlay/xy (ellipse 100 100 'solid 'blue) - 0 0 + -10 -10 (ellipse 120 120 'solid 'red)) => (overlay (ellipse 100 100 'solid 'blue) @@ -293,8 +334,8 @@ => (make-image (make-overlay - (make-translate 0 0 (image-shape (ellipse 100 50 'solid 'green))) - (make-translate 0 0 (image-shape (ellipse 50 100 'solid 'red)))) + (make-translate 0 25 (image-shape (ellipse 100 50 'solid 'green))) + (make-translate 25 0 (image-shape (ellipse 50 100 'solid 'red)))) (make-bb 100 100 100) @@ -307,9 +348,9 @@ (make-image (make-overlay (make-translate - 0 0 + 10 10 (make-overlay - (make-translate 0 0 (image-shape (ellipse 100 100 'solid 'blue))) + (make-translate 10 10 (image-shape (ellipse 100 100 'solid 'blue))) (make-translate 0 0 (image-shape (ellipse 120 120 'solid 'red))))) (make-translate 0 0 (image-shape (ellipse 140 140 'solid 'green)))) (make-bb 140 140 140) @@ -403,7 +444,7 @@ (test (beside (ellipse 50 100 'solid 'red) (ellipse 100 50 'solid 'blue)) => - (beside/align 'top + (beside/align 'center (ellipse 50 100 'solid 'red) (ellipse 100 50 'solid 'blue))) @@ -446,7 +487,7 @@ (test (above (ellipse 50 100 'solid 'red) (ellipse 100 50 'solid 'blue)) => - (above/align 'left + (above/align 'center (ellipse 50 100 'solid 'red) (ellipse 100 50 'solid 'blue))) @@ -458,14 +499,14 @@ (make-image (make-overlay (make-translate 0 0 (image-shape (ellipse 120 120 'solid 'red))) - (make-translate 0 0 (image-shape (ellipse 100 100 'solid 'blue)))) + (make-translate 10 10 (image-shape (ellipse 100 100 'solid 'blue)))) (make-bb 120 120 120) #f)) (test (underlay/xy (ellipse 100 100 'solid 'blue) - 0 0 + -10 -10 (ellipse 120 120 'solid 'red)) => (underlay (ellipse 100 100 'solid 'blue) @@ -503,8 +544,8 @@ => (make-image (make-overlay - (make-translate 0 0 (image-shape (ellipse 50 100 'solid 'red))) - (make-translate 0 0 (image-shape (ellipse 100 50 'solid 'green)))) + (make-translate 25 0 (image-shape (ellipse 50 100 'solid 'red))) + (make-translate 0 25 (image-shape (ellipse 100 50 'solid 'green)))) (make-bb 100 100 100) @@ -520,8 +561,8 @@ 0 0 (make-overlay (make-translate 0 0 (image-shape (ellipse 140 140 'solid 'green))) - (make-translate 0 0 (image-shape (ellipse 120 120 'solid 'red))))) - (make-translate 0 0 (image-shape (ellipse 100 100 'solid 'blue)))) + (make-translate 10 10 (image-shape (ellipse 120 120 'solid 'red))))) + (make-translate 10 10 (image-shape (ellipse 100 100 'solid 'blue)))) (make-bb 140 140 140) #f)) @@ -624,8 +665,9 @@ (make-translate 135 170 (make-ellipse 50 100 0 'solid "blue"))) (test (normalize-shape (image-shape - (beside (rectangle 10 10 'solid 'black) - (crop 0 0 5 5 (rectangle 10 10 'solid 'green))))) + (beside/align 'top + (rectangle 10 10 'solid 'black) + (crop 0 0 5 5 (rectangle 10 10 'solid 'green))))) => (make-overlay (make-polygon @@ -950,15 +992,27 @@ ;; curves ;; -(test (add-curve (rectangle 100 20 'solid 'black) - 10 10 0 1/4 - 90 10 0 1/4 - 'white) +;; make sure a curve stays roughly in the middle pixels by +;; covering up a white curve with a thin black bar +(test (overlay/align 'middle + 'middle + (rectangle 82 2 'solid 'black) + (add-curve (rectangle 100 20 'solid 'black) + 10 10 0 1/4 + 90 10 0 1/4 + 'white)) + => - (add-line (rectangle 100 20 'solid 'black) - 10 10 - 90 10 - 'white)) + (rectangle 100 20 'solid 'black)) + +;; and then make sure the curve actually draws something ... +(test (not (equal? (add-curve (rectangle 100 20 'solid 'black) + 10 10 0 1/4 + 90 10 0 1/4 + 'white) + (rectangle 100 20 'solid 'black))) + => + #t) (test (scale 2 (add-curve @@ -1133,11 +1187,13 @@ => #t) -(test (beside (rectangle 10 10 'solid 'black) - (crop 0 0 10 10 (rectangle 10 10 'solid 'green))) +(test (beside/align 'middle + (rectangle 10 10 'solid 'black) + (crop 0 0 10 10 (rectangle 10 10 'solid 'green))) => - (beside (rectangle 10 10 'solid 'black) - (rectangle 10 10 'solid 'green))) + (beside/align 'middle + (rectangle 10 10 'solid 'black) + (rectangle 10 10 'solid 'green))) (test (place-image (circle 4 'solid 'black) 10 10 @@ -1165,15 +1221,17 @@ -4 -4 (rectangle 40 40 'solid 'orange)) => - (overlay (crop 4 4 16 16 (circle 8 'solid 'black)) - (rectangle 40 40 'solid 'orange))) + (overlay/xy (crop 4 4 16 16 (circle 8 'solid 'black)) + 0 0 + (rectangle 40 40 'solid 'orange))) (test (place-image (circle 4 'solid 'black) -4 0 (rectangle 40 40 'solid 'orange)) => - (overlay (crop 4 0 4 8 (circle 4 'solid 'black)) - (rectangle 40 40 'solid 'orange))) + (overlay/xy (crop 4 0 4 8 (circle 4 'solid 'black)) + 0 0 + (rectangle 40 40 'solid 'orange))) (test (place-image/align (circle 4 'solid 'black) 5 10 'center 'center diff --git a/collects/mrlib/image-core.ss b/collects/mrlib/image-core.ss index 829dab3555..ee3855cf62 100644 --- a/collects/mrlib/image-core.ss +++ b/collects/mrlib/image-core.ss @@ -202,21 +202,21 @@ has been moved out). (init-field shape bb normalized?) (define/public (equal-to? that eq-recur) (or (eq? this that) - (and (not (skip-image-equality-fast-path)) ;; this is here to make testing more effective - (equal? (get-normalized-shape) (send that get-normalized-shape))) (and (is-a? that image%) (same-bb? bb (send that get-bb)) - (let ([w (round (inexact->exact (bb-right bb)))] - [h (round (inexact->exact (bb-bottom bb)))]) - (or (zero? w) - (zero? h) - (let ([bm1 (make-object bitmap% w h)] - [bm2 (make-object bitmap% w h)] - [bytes1 (make-bytes (* w h 4) 0)] - [bytes2 (make-bytes (* w h 4) 0)] - [bdc (make-object bitmap-dc%)]) - (and (check-same? bm1 bm2 bytes1 bytes2 bdc "red" that) - (check-same? bm1 bm2 bytes1 bytes2 bdc "green" that)))))))) + (or (and (not (skip-image-equality-fast-path)) ;; this is here to make testing more effective + (equal? (get-normalized-shape) (send that get-normalized-shape))) + (let ([w (+ 1 (round (inexact->exact (bb-right bb))))] ;; some shapes (ie, rectangles) draw 1 outside the bounding box + [h (+ 1 (round (inexact->exact (bb-bottom bb))))]) ;; so we make the bitmap slightly bigger to accomodate that. + (or (zero? w) + (zero? h) + (let ([bm1 (make-object bitmap% w h)] + [bm2 (make-object bitmap% w h)] + [bytes1 (make-bytes (* w h 4) 0)] + [bytes2 (make-bytes (* w h 4) 0)] + [bdc (make-object bitmap-dc%)]) + (and (check-same? bm1 bm2 bytes1 bytes2 bdc "red" that) + (check-same? bm1 bm2 bytes1 bytes2 bdc "green" that))))))))) (define/private (check-same? bm1 bm2 bytes1 bytes2 bdc color that) (clear-bitmap/draw/bytes bm1 bdc bytes1 this color) @@ -280,9 +280,7 @@ has been moved out). (define/override (copy) (make-image shape bb normalized?)) (define/override (draw dc x y left top right bottom dx dy draw-caret?) (let ([smoothing (send dc get-smoothing)]) - (send dc set-smoothing 'aligned) - (render-image this dc x y) - (send dc set-smoothing smoothing))) + (render-image this dc x y))) (define/override (get-extent dc x y [w #f] [h #f] [descent #f] [space #f] [lspace #f] [rspace #f]) (send (get-the-snip-class-list) add snip-class) @@ -524,12 +522,14 @@ has been moved out). (let ([pen (send dc get-pen)] [brush (send dc get-brush)] [font (send dc get-font)] - [fg (send dc get-text-foreground)]) + [fg (send dc get-text-foreground)] + [smoothing (send dc get-smoothing)]) (render-normalized-shape (send image get-normalized-shape) dc dx dy) (send dc set-pen pen) (send dc set-brush brush) (send dc set-font font) - (send dc set-text-foreground fg))) + (send dc set-text-foreground fg) + (send dc set-smoothing smoothing))) (define (render-normalized-shape shape dc dx dy) (cond @@ -556,20 +556,43 @@ has been moved out). (define (render-simple-shape simple-shape dc dx dy) (cond [(polygon? simple-shape) - (let ([path (polygon-points->path (polygon-points simple-shape))]) - (send dc set-pen (mode-color->pen (polygon-mode simple-shape) - (polygon-color simple-shape))) - (send dc set-brush (mode-color->brush (polygon-mode simple-shape) - (polygon-color simple-shape))) - (send dc draw-path path dx dy 'winding))] + (send dc set-pen (mode-color->pen (polygon-mode simple-shape) + (polygon-color simple-shape))) + (send dc set-brush (mode-color->brush (polygon-mode simple-shape) + (polygon-color simple-shape))) + (send dc set-smoothing (mode->smoothing (polygon-mode simple-shape))) + (cond + [(eq? (polygon-mode simple-shape) 'outline) + (let ([connect + (λ (p1 p2) + (let ([path (new dc-path%)]) + (send path move-to (point-x p1) (point-y p1)) + (send path line-to (point-x p2) (point-y p2)) + (send dc draw-path path dx dy)))]) + (let loop ([points (polygon-points simple-shape)]) + (cond + [(null? (cdr points)) + (connect (car points) (car (polygon-points simple-shape)))] + [else + (connect (car points) (cadr points)) + (loop (cdr points))])))] + [else + (let ([path (polygon-points->path (polygon-points simple-shape))]) + (send dc draw-path path dx dy 'winding))])] [(line-segment? simple-shape) - (let ([start (line-segment-start simple-shape)] - [end (line-segment-end simple-shape)]) + (let* ([start (line-segment-start simple-shape)] + [end (line-segment-end simple-shape)] + [path (new dc-path%)] + [sx (point-x start)] + [sy (point-y start)] + [ex (point-x end)] + [ey (point-y end)]) + (send path move-to sx sy) + (send path line-to ex ey) (send dc set-pen (line-segment-color simple-shape) 1 'solid) (send dc set-brush "black" 'transparent) - (send dc draw-line - (+ dx (point-x start)) (+ dy (point-y start)) - (+ dx (point-x end)) (+ dy (point-y end))))] + (send dc set-smoothing 'aligned) + (send dc draw-path path dx dy))] [(curve-segment? simple-shape) (let* ([path (new dc-path%)] [start (curve-segment-start simple-shape)] @@ -585,14 +608,15 @@ has been moved out). [ep (* (curve-segment-e-pull simple-shape) d)]) (send path move-to sx sy) (send path curve-to - (+ sx (* sp (cos sa))) - (- sy (* sp (sin sa))) - (- ex (* ep (cos ea))) - (+ ey (* ep (sin ea))) - ex - ey) + (+ sx (* sp (cos sa))) + (- sy (* sp (sin sa))) + (- ex (* ep (cos ea))) + (+ ey (* ep (sin ea))) + ex + ey) (send dc set-pen (curve-segment-color simple-shape) 1 'solid) (send dc set-brush "black" 'transparent) + (send dc set-smoothing 'aligned) (send dc draw-path path dx dy))] [else (let ([dx (+ dx (translate-dx simple-shape))] @@ -610,6 +634,7 @@ has been moved out). (send path rotate θ) (send dc set-pen (mode-color->pen (ellipse-mode atomic-shape) (ellipse-color atomic-shape))) (send dc set-brush (mode-color->brush (ellipse-mode atomic-shape) (ellipse-color atomic-shape))) + (send dc set-smoothing (mode->smoothing (ellipse-mode atomic-shape))) (send dc draw-path path dx dy)))] [(bitmap? atomic-shape) (let ([bm (get-rendered-bitmap atomic-shape)]) @@ -647,6 +672,34 @@ has been moved out). (send path line-to (round (point-x (car points))) (round (point-y (car points)))) path)) +(define (points->bb-path points) + (let ([path (new dc-path%)]) + (let-values ([(left top right bottom) (points->ltrb-values points)]) + (send path move-to left top) + (send path line-to right top) + (send path line-to right bottom) + (send path line-to left bottom) + (send path line-to left top) + path))) + +;; points->ltrb-values : (cons point (listof points)) -> (values number number number number) +(define (points->ltrb-values points) + (let* ([fx (point-x (car points))] + [fy (point-y (car points))] + [left fx] + [top fy] + [right fx] + [bottom fy]) + (for-each (λ (point) + (let ([new-x (point-x point)] + [new-y (point-y point)]) + (set! left (min new-x left)) + (set! top (min new-y top)) + (set! right (max new-x right)) + (set! bottom (max new-y bottom)))) + (cdr points)) + (values left top right bottom))) + #| the mask bitmap and the original bitmap are all together in a single bytes! @@ -766,13 +819,17 @@ the mask bitmap and the original bitmap are all together in a single bytes! (define (degrees->radians θ) (* θ 2 pi (/ 360))) +(define (mode->smoothing mode) + (case mode + [(outline) 'aligned] + [(solid) 'smoothed])) + (define (mode-color->pen mode color) - (send the-pen-list find-or-create-pen - (get-color-arg color) - 1 - (case mode - [(outline) 'solid] - [(solid) 'transparent]))) + (case mode + [(outline) + (send the-pen-list find-or-create-pen (get-color-arg color) 1 'solid)] + [(solid) + (send the-pen-list find-or-create-pen "black" 1 'transparent)])) (define (mode-color->brush mode color) (send the-brush-list find-or-create-brush @@ -820,7 +877,8 @@ the mask bitmap and the original bitmap are all together in a single bytes! degrees->radians normalize-shape ellipse-rotated-size - + points->ltrb-values + image? text->font diff --git a/collects/teachpack/2htdp/scribblings/image-toc.ss b/collects/teachpack/2htdp/scribblings/image-toc.ss index c1204b96a1..d6e0211399 100644 --- a/collects/teachpack/2htdp/scribblings/image-toc.ss +++ b/collects/teachpack/2htdp/scribblings/image-toc.ss @@ -25,14 +25,13 @@ (list '(image-width (circle 30 "solid" "orange")) 'val 60) (list '(image-width (ellipse 30 40 "solid" "orange")) 'val 30) (list - '(beside/align - "bottom" + '(beside (ellipse 20 70 "solid" "lightsteelblue") (frame (ellipse 20 50 "solid" "mediumslateblue")) (ellipse 20 30 "solid" "slateblue") (ellipse 20 10 "solid" "navy")) 'image - "f7f1480d58.png") + "54a488e1a5.png") (list '(frame (ellipse 20 20 "outline" "black")) 'image "6a5a617f28.png") (list '(above @@ -163,13 +162,13 @@ "2bea495d1f.png") (list '(above/align - "center" + "left" (ellipse 70 20 "solid" "yellowgreen") (ellipse 50 20 "solid" "olivedrab") (ellipse 30 20 "solid" "darkolivegreen") (ellipse 10 20 "solid" "darkgreen")) 'image - "166bb7bc683.png") + "ff11314e4e.png") (list '(above/align "right" @@ -193,13 +192,13 @@ "2187216ca96.png") (list '(beside/align - "center" + "top" (ellipse 20 70 "solid" "mediumorchid") (ellipse 20 50 "solid" "darkorchid") (ellipse 20 30 "solid" "purple") (ellipse 20 10 "solid" "indigo")) 'image - "2dd0a2a4517.png") + "10a0d35fa03.png") (list '(beside/align "bottom" @@ -265,12 +264,12 @@ "ff2fcb7b87.png") (list '(underlay/align - "middle" + "left" "middle" (rectangle 30 60 "solid" "orange") (ellipse 60 30 "solid" "purple")) 'image - "2d1e52503d7.png") + "1404e4b2af.png") (list '(underlay (ellipse 10 60 "solid" "red") @@ -335,21 +334,21 @@ "969a9aa483.png") (list '(overlay/align - "middle" + "left" "middle" (rectangle 30 60 "solid" "orange") (ellipse 60 30 "solid" "purple")) 'image - "bf08c71801.png") + "11b64ab4d3.png") (list '(overlay (regular-polygon 20 5 "solid" (make-color 50 50 255)) - (regular-polygon 25 5 "solid" (make-color 100 100 255)) - (regular-polygon 30 5 "solid" (make-color 150 150 255)) - (regular-polygon 35 5 "solid" (make-color 200 200 255)) - (regular-polygon 40 5 "solid" (make-color 250 250 255))) + (regular-polygon 26 5 "solid" (make-color 100 100 255)) + (regular-polygon 32 5 "solid" (make-color 150 150 255)) + (regular-polygon 38 5 "solid" (make-color 200 200 255)) + (regular-polygon 44 5 "solid" (make-color 250 250 255))) 'image - "1aea411192a.png") + "1acede17bc6.png") (list '(overlay (ellipse 10 10 "solid" "red") diff --git a/collects/teachpack/2htdp/scribblings/image.scrbl b/collects/teachpack/2htdp/scribblings/image.scrbl index b50aed1def..4ea193ef52 100644 --- a/collects/teachpack/2htdp/scribblings/image.scrbl +++ b/collects/teachpack/2htdp/scribblings/image.scrbl @@ -310,10 +310,10 @@ mean that the curve stays with the angle longer. (ellipse 50 50 "solid" "red") (ellipse 60 60 "solid" "black")) (overlay (regular-polygon 20 5 "solid" (make-color 50 50 255)) - (regular-polygon 25 5 "solid" (make-color 100 100 255)) - (regular-polygon 30 5 "solid" (make-color 150 150 255)) - (regular-polygon 35 5 "solid" (make-color 200 200 255)) - (regular-polygon 40 5 "solid" (make-color 250 250 255)))] + (regular-polygon 26 5 "solid" (make-color 100 100 255)) + (regular-polygon 32 5 "solid" (make-color 150 150 255)) + (regular-polygon 38 5 "solid" (make-color 200 200 255)) + (regular-polygon 44 5 "solid" (make-color 250 250 255)))] } @@ -323,7 +323,7 @@ mean that the curve stays with the angle longer. @scheme[x-place] and @scheme[y-place] are both @scheme["middle"], then the images are lined up on their centers. - @image-examples[(overlay/align "middle" "middle" + @image-examples[(overlay/align "left" "middle" (rectangle 30 60 "solid" "orange") (ellipse 60 30 "solid" "purple")) (overlay/align "right" "bottom" @@ -383,7 +383,7 @@ mean that the curve stays with the angle longer. @scheme[x-place] and @scheme[y-place] are both @scheme["middle"], then the images are lined up on their centers. - @image-examples[(underlay/align "middle" "middle" + @image-examples[(underlay/align "left" "middle" (rectangle 30 60 "solid" "orange") (ellipse 60 30 "solid" "purple")) (underlay/align "right" "top" @@ -446,7 +446,7 @@ mean that the curve stays with the angle longer. (ellipse 20 30 "solid" "slateblue") (ellipse 20 10 "solid" "navy")) - (beside/align "center" + (beside/align "top" (ellipse 20 70 "solid" "mediumorchid") (ellipse 20 50 "solid" "darkorchid") (ellipse 20 30 "solid" "purple") @@ -484,7 +484,7 @@ mean that the curve stays with the angle longer. (ellipse 30 20 "solid" "darkgoldenrod") (ellipse 10 20 "solid" "sienna")) - (above/align "center" + (above/align "left" (ellipse 70 20 "solid" "yellowgreen") (ellipse 50 20 "solid" "olivedrab") (ellipse 30 20 "solid" "darkolivegreen") @@ -622,11 +622,11 @@ and universes using @scheme[2htdp/universe]. debug image constructions, i.e., to see where certain sub-images appear within some larger image. - @image-examples[(beside/align "bottom" - (ellipse 20 70 "solid" "lightsteelblue") - (frame (ellipse 20 50 "solid" "mediumslateblue")) - (ellipse 20 30 "solid" "slateblue") - (ellipse 20 10 "solid" "navy"))] + @image-examples[(beside + (ellipse 20 70 "solid" "lightsteelblue") + (frame (ellipse 20 50 "solid" "mediumslateblue")) + (ellipse 20 30 "solid" "slateblue") + (ellipse 20 10 "solid" "navy"))] } @section{Image Properties} @@ -754,63 +754,4 @@ The baseline of an image is the place where the bottoms any letters line up, not Two images are equal if they draw exactly the same way, at their current size (not neccessarily at all sizes). -@;{ -Image equality testing is done structurally, i.e., based on -the construction of the image, -although with certain, expected equivalences. For example, -two rectangles with the same width, height, color, and mode -are equal. Similarly, constructing a 20x10 rectangle and -then rotating it by 90 degress is equal to a 10x20 rectangle -(provided they have the same color and mode). - -Equality testing may contain a few nuances, though: -@itemize[ - @item{Overlaying two images in opposite orders is never equal. For example, - these two images are not @scheme[equal]: - @schemeblock[(overlay/xy (rectangle 30 10 "solid" "blue") - 0 - 10 - (rectangle 30 10 "solid" "red"))] - @schemeblock[(overlay/xy (rectangle 30 10 "solid" "red") - 0 - -10 - (rectangle 30 10 "solid" "blue"))] - even thought they may appear to be the same when drawn. - - The rationale for them being different is that, at some scale factor, - they will draw differently; specifically when they are scaled down - far enough, the first will appear to be a single red pixel and the second will appear to - be a single blue pixel.} - @item{When rotating images, the internal calculations involve real numbers, not just - rationals and thus must be approximated with Scheme's inexact numbers, causing - small roundoff errors that make the images draw slightly differently. - - To combat this problem, use @scheme[equal~?] to compare the images, - or @scheme[check-within] for test suites involving images.} - - @item{Combining a series of line segments to form a polygon produces - an image that is different than the polygon.} - - @item{In order to make equality on images created with - @scheme[text] and @scheme[text/font] - work well, each string passed to either of those functions results - in a number of horizontally aligned images, one for each letter in the - string. This means that, for example - @schemeblock[(equal? (beside/align "baseline" - (text "a" 18 "black") - (text "b" 18 "black")) - (text "ab" 18 "black"))] - is true, but that subtle aspects of font drawing may be wrong, since - the underlying toolkit only gets a single letter at a time, instead - of the entire word (or sentence). - - The most obvious way that this shows up is in the handling of ligatures. - For example, the letter combinations ``ff'' and ``fi'' and ``fl'' are - generally drawn intertwined when they appear together, and thus an ``f'' - drawn separately from an ``i'' looks different than the ligature ``fi''. - For example, here is how 24 point Times font looks when the word ``refill'' - is drawn, first with ligatures and then without: - @centerline{@image["2htdp/scribblings/ligature.png"]}. - } -] -} +@include-section["porting-guide.scrbl"] diff --git a/collects/teachpack/2htdp/scribblings/img/10a0d35fa03.png b/collects/teachpack/2htdp/scribblings/img/10a0d35fa03.png new file mode 100644 index 0000000000000000000000000000000000000000..43e80fad7c0cc69f68ee111272eb75f3f1cf8124 GIT binary patch literal 2345 zcmV+^3D)+BP)tFmi&w*xpC~+jkBcblGJgUcty4~$dGkwuY^e9i zK*#62l?{`l%JDtvp?4&hIUHvYt=Yr3JiwHiT=@6kt1lcs{pNrqW-DA7(bVcK?c1L0 z?ONBOwdiObe?NZq`5US-qrJAsJ$_nc_Dn==*VN1=%+b%ZGL) z#fW~yQ3zH&!F7Mjnr~4R_2=Jx)Pp+& zIaOA0p5wbykt?}@jb4jZJztmCUphH>VQhxx#E=;NPpq7Q6weO7J*oRvIwqh0{aEGx zLZ=fq--{PDe(+*CJy~5a0Aw@p-m_`#wS}#oS#(iVxN>ZGhUTGv+$xjBKR)3tea+_% zgr#JqM51x#SE0hg#E^3J4|;Q<456d)$h$HC^ls~7uw?sMT(i<{mq1vHEtf3lcNd%-1pGZ7f$Y2 z@j$B)E0@o<{n=0LJGFCBhZhQSSm=$&i@5gBh;|1~jjOQ%qn}hB zH4E2Xm$cWd%j@?Z+`jMBHy(bXr=`{x>&vJ+gZ}%je=E_eYV` zi8I9sMwj$0X{tZvZs)Z_DX9#Vc)kMho0;)TLftZZo@J>T#u(@Re{n4soiZ|-WOaB!KzotnMSXay|tDSy&~jak6$ujs4;pr0RTqs z$-0P9H8F(wd1>S{M=lGM&nqN)C7GYnryRAL=g*b&-Uu zFqB&!VE9>1DU)WpD{D~RL0>aF#cGx>7i?y zlLUTtwBV21y%=+kp@FG6GbLxH-)= zHH*yc5pp!%N91GxK#Hu25tF+c000n1i1Lsm%8l!AL8Koh(8Acw&CJfntUxrE0RT`YjuY4bkec&zIeHc(&z)w5Ljb_KsSW#Vlz~jV z^iekOS<>vKfj^(+l%f)BkNBEgDr)Lw*6iUc&(g*oX3ZWRyRRY;$+#5}e}7~3OsC(@ z$JoA?Z8WE^JGj}h>DP8NJ3a=;*GceDan~dOz`1919o%g3cGKs6Cied&lP`wy_0&C& zb4#|dB#ZM>h%~c2{#f|hV#hiBXx(%Cy-#x!XS1>Xtamx>Tgl8y(kg;TvjtbP#fI$l z`oU`TP>VJ)i#C!jJSspGGz^Pr?hbI(Pr7XoX{N2Xd!yC`s~J%gVsK5RN(UK; z=JC^s#X$przsF^<8U5@QZ>quWZni+$xG|s*#kv^)V0hH|g*qc9?ts)rS74wTCFb=i7;;Kv-`Z2(b-;=DNZHTxoKX=CR@zRfQ!aW+p^bb=c_TlRObxHIT> zzyJW>z^2Abe;w;6Q|oByaXs?a?vdkD(d+4kPdMtA+eybb+b{rNYhWkOn>4f0T=`!d zAe!>`y63~KSQi8Ue1qxOb_8?+d!c{;fUh@QP%RhO3jzcHwkFd~a|Rc8K%f-=ISi=7DL(FzR2qEFW{Rq6xPG)*BB~CHf@+M+aqiWG_S6%nWFx` zG`kk_6_(H%HQf%pP1wAmU@2n2hyKsh-rnKd5oRpES~k^Is2?~2T%EBwKhK$=ne$ni z%U5tZwl|jkZfhY@yv%Ouxw?Cu-QQ_3yYZUO=>HD~01$@7Tjvw5#r%TaHtO;}2onDQy7)IG P00000NkvXXu0mjfU6Pg^ literal 0 HcmV?d00001 diff --git a/collects/teachpack/2htdp/scribblings/img/11b64ab4d3.png b/collects/teachpack/2htdp/scribblings/img/11b64ab4d3.png new file mode 100644 index 0000000000000000000000000000000000000000..f19b1c706a264536abfd5347f097ca0c297fe957 GIT binary patch literal 742 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 VZtv`py8!?I002ovPDHLkV1n>xkFR diff --git a/collects/teachpack/2htdp/scribblings/img/1acede17bc6.png b/collects/teachpack/2htdp/scribblings/img/1acede17bc6.png new file mode 100644 index 0000000000000000000000000000000000000000..4caa13ad8a0dd201a40697ddf8c6ca400414f23d GIT binary patch literal 1572 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 m$ns#o+{l<)^SS|71o%JHnlAD&iZD6=0000(Kc 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 diff --git a/collects/teachpack/2htdp/scribblings/img/ff11314e4e.png b/collects/teachpack/2htdp/scribblings/img/ff11314e4e.png new file mode 100644 index 0000000000000000000000000000000000000000..aa773bfbf453c3cf5ae313e7bd3c9a02b452d1b1 GIT binary patch literal 2264 zcmV;}2q*W6P)=4h=fA5U^5gzqN1)Fc7;*)MoPj|nH|XJp1(BC%Vj3w_x{A(I(z!}H zhh=hDI#0zEAV|z#0fs+U-k{CuX|sCTte!g~-u95-lk7PbC_=848+ECrS*c}Oxsf8| z;rE|Cl`~-K9lzLXZyNEo10d-V#SVlhJFU{7-j=W0EF)59-)Cy7kl^ne{o6fT-KeiK zQ6^)DfU+ER{nCs*Im)%uh9**pqR?ThYk7FWAF?OIp(N7fOIBz9WI13@BNS&3*;xgqZ; zgecj5@USZT$7;qf@x1DHeD!7D5sr5!+g0qy2*tXbpDoht1XJf0o}l$#rsKWiO^@3Y zDIyS}BF(O+^#>I)-Ncq@^S}{r`)$jq0mtQ#5J-l@=wL{;NVBUXvnGwsp1OVZ*)7Mr zd+h({9Br_8ZYRoN6fh*4ui8|gs$P&*F>8eqp%QU%LqpE%X4iGI`?@bU8aJPjp$K`F zqD-qO)u)x~6r~7;s|+Kgnu^`uGwi-O=Ib2uJs9(KbG!?O+c{xKR?QexOra*lpi3>) zFh%pfQAd$#8gB04n6KLr=yP+!9?t3sTHV~RFElEOLR303LZP5^aw=0!Wh!Ku3QDJD z3e_ov45^OI7>G8NAo4EnsLNv;_gGwBo7+1!Z3htuJn#uHAOa3Rk!EO`rb&{ZWpavO zWQ0OSq>@NZ5h)as(}XgG(vT=6X7_Uup>H9G{D9?-$#TbJy=$`GHQVmGt8TBS}KGEWfI3(Kch@7CFOW z*Pous&$++4d8+9@AA9`c*gtG0Btcay``-4-*VEaB7-c6@2?F1E<78vY@4X4hGZlo0 zilxszyZ%j9p~WINk;>t*{;vLDza^Q^Tsfnv-Fj@f;XBf$peTxN-`Mdp`)uO_(&ePO zf#{_z@2xYwBvA(e08U+a^Kpm-01!pt?8T$^`majVK?9by_P)zlJYhi)`9C$jBM6eZ z+^B2t8ZJY)7_FgH6BSw~n%L+yc^yN|xN2P{pnu_p>A;B08 zTMG1LQWOxIs(oS8Q3xO|PZG)18TW5HE>VO80IV)~UKEA1O-Dj}GJj(bz_rGjJsaL; zWKuhMlQX8Fk&e@i@AMDfl58&)GE})QZu&)W{st^+kIZgGAl~h{biVn+L}puB1*S^OHt^R4iG0cW?lWx&#A9qYB&d#v`}K+qfh z5CjReQm<7NWUBIX8bg7;Y++_G#>*@W;Zg-doY~T6w)T&Vnx~y88AYqr8dj+UNbvaW z9^ZH%=%FdOoM9D=O3tWK8MQi1PY_a9PQ=D6eG8A*`R~@oYpqRfoz0<8gnRu0UH-b2 z+t*j@)Mw_#$6+iya;^fL|Jz|q;uYnBfw~JP z@oGi|YP;Voaf#rpT)Fmz+v~tCJ5P|+HW&|GUf{d>+Tx)+9}q9Cn-d1Jr9V!}5kWGF zj+1m@&eAw3M+6yiOX8ucQE30s*0T(DtBQNj1~j{s4U&QXX_7eDV7zlJ5>8F-mfWICTF(|7f=1M{?~#Kd%+7K z+PnS03p)-Xl;l-Wk5nQZ4_Z#1`Q_knPYgmu1En3w+bpe>wl< z>3L>@5IwcHV*4{MKW%&_xmVp(=B)7ByIPuC8}D>pGd=8{IhrbGml(>57p+*cVq3=J zQ7KMkGS$G?KwV26$8))w+?t9S^uGp>(`_HJ^jd90cE<>-OwUkfWoYzS899&7nVHE% zs)kz)H79C(!HGXi9H=^Qa(^->-4cPKD4NDhB}YqK{zrNhpB?;c-^zW-vLz7&0C@lW z`_m!;0FKljiARN!7!ViYPB)*PIneR2Ram*>;@O;=D^Ll z#?G~!OQaQypke3mTw~oM-FEMj_ZJ@k0GfH9_!dzVZx23>>uw{0sIU$GUYn#90?8u6 z