summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chickadee/render/sprite.scm100
1 files changed, 96 insertions, 4 deletions
diff --git a/chickadee/render/sprite.scm b/chickadee/render/sprite.scm
index 7e87494..f85ae93 100644
--- a/chickadee/render/sprite.scm
+++ b/chickadee/render/sprite.scm
@@ -27,7 +27,8 @@
#:use-module (chickadee render texture)
#:use-module (chickadee render vertex-buffer)
#:export (draw-sprite
- with-batched-sprites))
+ with-batched-sprites
+ draw-nine-patch))
(define default-shader
(delay
@@ -275,9 +276,10 @@ void main (void) {
(lambda ()
(set! *batch?* #f)))))
+(define %default-texture-rect (make-rect 0.0 0.0 1.0 1.0))
+
(define draw-sprite
- (let ((rect (make-rect 0.0 0.0 0.0 0.0))
- (default-texture-rect (make-rect 0.0 0.0 1.0 1.0)))
+ (let ((rect (make-rect 0.0 0.0 0.0 0.0)))
(lambda* (texture dimensions #:key
scale rotation (blend-mode 'alpha)
texture-rect
@@ -289,7 +291,7 @@ void main (void) {
(set-rect-height! rect (texture-height texture))
rect)
dimensions))
- (texture-rect (or texture-rect default-texture-rect)))
+ (texture-rect (or texture-rect %default-texture-rect)))
(if *batch?*
(draw-sprite-batched texture dimensions
scale rotation blend-mode shader
@@ -297,3 +299,93 @@ void main (void) {
(draw-sprite-unbatched texture dimensions
scale rotation blend-mode shader
texture-rect))))))
+
+
+;;;
+;;; Nine Patches
+;;;
+
+(define draw-nine-patch
+ (let ((rect (make-rect 0.0 0.0 0.0 0.0))
+ (trect (make-rect 0.0 0.0 0.0 0.0)))
+ (lambda* (texture dimensions #:key (margin 0)
+ (top-margin margin) (bottom-margin margin)
+ (left-margin margin) (right-margin margin)
+ (texture-rect %default-texture-rect)
+ scale rotation (blend-mode 'alpha)
+ (shader (force default-shader)))
+ "Draw a \"nine patch\" sprite. A nine patch sprite renders
+TEXTURE as a WIDTH x HEIGHT rectangle whose stretchable areas are
+defined by the given margin measurements. The corners are never
+stretched, the left and right edges may be stretched vertically, the
+top and bottom edges may be stretched horizontally, and the center may
+be stretched in both directions. This rendering technique is
+particularly well suited for resizable windows and buttons in
+graphical user interfaces.
+
+MARGIN specifies the margin size for all sides of the nine patch. To
+make margins of differing sizes, the TOP-MARGIN, BOTTOM-MARGIN,
+LEFT-MARGIN, and RIGHT-MARGIN arguments may be used."
+ (let* ((w (rect-width dimensions))
+ (h (rect-height dimensions))
+ (border-x1 (rect-left dimensions))
+ (border-y1 (rect-bottom dimensions))
+ (border-x2 (rect-right dimensions))
+ (border-y2 (rect-top dimensions))
+ (fill-x1 (+ border-x1 left-margin))
+ (fill-y1 (+ border-y1 bottom-margin))
+ (fill-x2 (- border-x2 right-margin))
+ (fill-y2 (- border-y2 top-margin))
+ (tw (texture-width texture))
+ (th (texture-width texture))
+ (border-s1 (rect-left texture-rect))
+ (border-t1 (rect-bottom texture-rect))
+ (border-s2 (rect-right texture-rect))
+ (border-t2 (rect-top texture-rect))
+ (fill-s1 (+ border-s1 (/ left-margin tw)))
+ (fill-t1 (+ border-t1 (/ bottom-margin th)))
+ (fill-s2 (- border-s2 (/ right-margin tw)))
+ (fill-t2 (- border-t2 (/ top-margin th))))
+ (define (draw-piece x1 y1 x2 y2 s1 t1 s2 t2)
+ (set-rect-x! rect x1)
+ (set-rect-y! rect y1)
+ (set-rect-width! rect (- x2 x1))
+ (set-rect-height! rect (- y2 y1))
+ (set-rect-x! trect s1)
+ (set-rect-y! trect t1)
+ (set-rect-width! trect (- s2 s1))
+ (set-rect-height! trect (- t2 t1))
+ (draw-sprite texture rect
+ #:texture-rect trect
+ #:scale scale
+ #:rotation rotation
+ #:blend-mode blend-mode
+ #:shader shader))
+ (with-batched-sprites
+ ;; bottom-left
+ (draw-piece border-x1 border-y1 fill-x1 fill-y1
+ border-s1 border-t1 fill-s1 fill-t1)
+ ;; bottom-center
+ (draw-piece fill-x1 border-y1 fill-x2 fill-y1
+ fill-s1 border-t1 fill-s2 fill-t1)
+ ;; dbottom-right
+ (draw-piece fill-x2 border-y1 border-x2 fill-y1
+ fill-s2 border-t1 border-s2 fill-t1)
+ ;; center-left
+ (draw-piece border-x1 fill-y1 fill-x1 fill-y2
+ border-s1 fill-t1 fill-s1 fill-t2)
+ ;; center
+ (draw-piece fill-x1 fill-y1 fill-x2 fill-y2
+ fill-s1 fill-t1 fill-s2 fill-t2)
+ ;; center-right
+ (draw-piece fill-x2 fill-y1 border-x2 fill-y2
+ fill-s2 fill-t1 border-s2 fill-t2)
+ ;; top-left
+ (draw-piece border-x1 fill-y2 fill-x1 border-y2
+ border-s1 fill-t2 fill-s1 border-t2)
+ ;; top-center
+ (draw-piece fill-x1 fill-y2 fill-x2 border-y2
+ fill-s1 fill-t2 fill-s2 border-t2)
+ ;; top-right
+ (draw-piece fill-x2 fill-y2 border-x2 border-y2
+ fill-s2 fill-t2 border-s2 border-t2))))))