racket/collects/picturing-programs/private/tiles.rkt
2012-04-25 17:05:56 -04:00

164 lines
7.1 KiB
Racket

#lang racket/base
; Modified 1/19/2005 to be compatible with new image.ss contracts.
; Modified 2/16/2005 to include stuff from world.ss as well as image.ss
; Modified 2/17/2005 to provide on-update-event (which requires overriding a few
; functions from world.ss)
; Modified 5/20/2005 to rename on-update-event as on-redraw-event, and
; handle pinholes more consistently in image-beside and image-above.
; Modified 1/26/2006 to remove the functions I was replacing in image.ss
; (since image.ss now does things the way I wanted) and
; to remove my tweaked copy of world.ss (since world.ss now does things the
; way I wanted).
; Modified 7/12/2006 to allow image-beside and image-above to take variable numbers of arguments.
; Modified 7/26/2006 to add image-beside-align-top, image-beside-align-bottom, image-above-align-left, and image-above-align-right.
; Modified 12/17/2007 to add crop-top, crop-bottom, crop-left, crop-right. Also utility functions slice-pic and unslice-pic.
; Modified 12/26/2007 to provide all-from image.ss, so we never have to mention image.ss at all.
; Modified 8/15/2008 to add image-above-align-center and image-beside-align-center.
; Modified 10/28/2008 to use provide/contract (and 4.x-style module specs, rather than (lib blah blah))
; Modified again 10/28/2008 to do more user-friendly "check-arg"-style checking instead.
; Modified 1/3/2009 to fix bugs in crop-* and unslice-pic related to zero-sized images.
; Modified 7/9/2009 for compatibility with DrScheme 4.2
; Modified 10/19/2009 for compatibility with DrScheme 4.2.2: image? is now in htdp/image, so it doesn't need to be required from htdp/advanced.
; Modified 1/12/2010: renamed image-above et al to above et al, image-beside et al to beside et al.
; place-image and scene+line are now defined in sb-universe, so they don't need to be here.
; Modified 1/30/2010 for compatibility with 4.2.4: require 2htdp/private/universe-image, which
; has a bunch of functions that accept both htdp-style images and 2htdp-style images.
; Modified 2/10/2010: replaced color-list with alpha-color-list to fix transparency bug.
; Modified 5/24/2010: eliminated all reference to pinholes, scenes, and htdp/image.
; Now using purely 2htdp/image, 2htdp/universe. Downside: no reflection primitives.
; Modified 6/23/2010: had rotate-cw and rotate-ccw reversed. And now we DO have reflection,
; so I'm putting it back in -- at least for vertical and horizontal axes.
; Modified 6/26/2010 to rename .ss to .rkt, lang scheme to lang racket, etc.
; Modified 7/2/2010: I did NOT have rotate-cw and rotate-ccw reversed; there's a bug in
; rotate that causes them to work incorrectly on bitmaps. Reversing them back.
; Modified 12/13/2010: Added flip-main and flip-other (formerly known as
; reflect-main-diag and reflect-other-diag, which had been disabled for
; a while).
; Modified 8/??/2011: reworded a bunch of error messages in accordance
; with Guillaume & Kathi's research.
; Modified 10/??/2011: fixed error messages in crop functions.
(require
2htdp/image
lang/error ; check-arg, check-image, etc.
)
(provide
(all-from-out 2htdp/image)
; above above-align-right above-align-left above-align-center ; included in 2htdp/image
; beside beside-align-top beside-align-bottom beside-align-center ; include in 2htdp/image
reflect-vert reflect-horiz ; synonyms for flip-vertical and flip-horizontal, respectively
reflect-main-diag reflect-other-diag
flip-main flip-other ; synonyms for the above
rotate-cw rotate-ccw rotate-180 ; will simply call rotate
; show-pinhole ; what's a pinhole?
crop-top crop-bottom crop-left crop-right) ; will simply call crop
;; Symbol Any String String *-> Void
(define (check-image tag i rank . other-message)
(if (and (pair? other-message) (string? (car other-message)))
(check-arg tag (image? i) (car other-message) rank i)
(check-arg tag (image? i) "image" rank i)))
; reflect-horiz : image => image
(define (reflect-horiz picture)
(check-image 'reflect-horiz picture "first")
(flip-horizontal picture))
; reflect-vert : image => image
(define (reflect-vert picture)
(check-image 'reflect-vert picture "first")
(flip-vertical picture))
; reflect-main-diag : image => image
(define (reflect-main-diag picture)
(check-image 'reflect-main-diag picture "first")
(rotate -45 (flip-vertical (rotate 45 picture))))
; there ought to be a more efficient way than this....
; reflect-other-diag : image => image
(define (reflect-other-diag picture)
(check-image 'reflect-other-diag picture "first")
(rotate 45 (flip-vertical (rotate -45 picture))))
; synonyms
(define (flip-main picture)
(check-image 'flip-main picture "first")
(reflect-main-diag picture))
(define (flip-other picture)
(check-image 'flip-other picture "first")
(reflect-other-diag picture))
; natural-number? anything -> boolean
(define (natural-number? x)
(and (integer? x) (>= x 0)))
; natural-bounded? natural anything -> boolean
(define (natural-bounded? max x)
(and (natural-number? x) (<= x max)))
; crop-left : image natural-number -> image
; deletes that many pixels from left edge of image
(define (crop-left picture pixels)
(check-image 'crop-left picture "first")
(check-arg 'crop-left (natural-bounded? (image-width picture) pixels)
(format "natural number <= ~a" (image-width picture))
"second" pixels)
(crop pixels 0
(- (image-width picture) pixels) (image-height picture)
picture))
; crop-top : image number -> image
; deletes that many pixels from top edge of image
(define (crop-top picture pixels)
(check-image 'crop-top picture "first")
(check-arg 'crop-top (natural-bounded? (image-height picture) pixels)
(format "natural number <= ~a" (image-height picture))
"second" pixels)
(crop 0 pixels
(image-width picture) (- (image-height picture) pixels)
picture))
; crop-right : image number -> image
; deletes that many pixels from right edge of image
(define (crop-right picture pixels)
(check-image 'crop-right picture "first")
(check-arg 'crop-right (natural-bounded? (image-width picture) pixels)
(format "natural number <= ~a" (image-width picture))
"second" pixels)
(crop 0 0
(- (image-width picture) pixels)
(image-height picture)
picture))
; crop-bottom : image number -> image
; deletes that many pixels from bottom edge of image
(define (crop-bottom picture pixels)
(check-image 'crop-bottom picture "first")
(check-arg 'crop-bottom (natural-bounded? (image-height picture) pixels)
(format "natural number <= ~a" (image-height picture))
"second" pixels)
(crop 0 0
(image-width picture)
(- (image-height picture) pixels)
picture))
; rotate-cw : image => image
(define (rotate-cw picture)
(check-image 'rotate-cw picture "first")
(rotate -90 picture))
; rotate-ccw : image => image
; Ditto.
(define (rotate-ccw picture)
(check-image 'rotate-ccw picture "first")
(rotate 90 picture))
; rotate-180 : image => image
(define (rotate-180 picture)
(check-image 'rotate-180 picture "first")
(rotate 180 picture))