1 (in-package :score-pane
)
2 (defparameter *inactive-colour
* +black
+) ;; +gray50+
3 (defclass score-view
(view)
4 ((light-glyphs-ink :initform
*inactive-colour
* :initarg
:light-glyphs-ink
:accessor light-glyphs-ink
)
5 (%number-of-pages
:initform
"-" :accessor number-of-pages
)
6 (%current-page-number
:initform
"-" :accessor current-page-number
)))
8 (defclass score-pane
(esa-pane-mixin application-pane
) ())
10 (defmethod initialize-instance :after
((pane score-pane
) &rest args
)
11 (declare (ignore args
))
12 (setf (stream-default-view pane
) (make-instance 'score-view
)))
14 (defparameter *font
* nil
)
15 (defparameter *fonts
* (make-array 100 :initial-element nil
))
17 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21 (defclass score-output-record
(displayed-output-record)
22 ((parent :initarg
:parent
:initform nil
:accessor output-record-parent
)
23 (x :initarg
:x1
:initarg
:x-position
)
24 (y :initarg
:y1
:initarg
:y-position
)
27 (ink :initarg
:ink
:reader displayed-output-record-ink
)))
29 (defmethod initialize-instance :after
((record score-output-record
)
31 (declare (ignore size
))
32 (with-slots (x y width height
) record
33 (setf width
(abs (- x2 x
))
34 height
(abs (- y2 y
)))))
36 (defmethod bounding-rectangle* ((record score-output-record
))
37 (with-slots (x y width height
) record
38 (values x y
(+ x width
) (+ y height
))))
40 (defmethod output-record-position ((record score-output-record
))
41 (with-slots (x y
) record
44 (defmethod (setf output-record-position
) (new-x new-y
(record score-output-record
))
45 (with-slots (x y
) record
46 (setf x new-x y new-y
)))
48 (defmethod output-record-start-cursor-position ((record score-output-record
))
51 (defmethod (setf output-record-start-cursor-position
) (x y
(record score-output-record
))
52 (declare (ignore x y
))
55 (defmethod output-record-end-cursor-position ((record score-output-record
))
58 (defmethod (setf output-record-end-cursor-position
) (x y
(record score-output-record
))
59 (declare (ignore x y
))
62 (defmethod output-record-hit-detection-rectangle* ((record score-output-record
))
63 (bounding-rectangle* record
))
65 (defmethod output-record-refined-position-test ((record score-output-record
) x y
)
66 (declare (ignore x y
))
69 ;;; remove this when McCLIM is fixed
70 (defmethod region-intersects-region-p (region (record score-output-record
))
71 (with-bounding-rectangle* (x1 y1 x2 y2
) record
72 (region-intersects-region-p region
(make-rectangle* x1 y1 x2 y2
))))
74 ;;;;;;;;;;;;;;;;;; pixmap drawing
76 (climi::def-grecording draw-pixmap
(() pixmap pm-x pm-y
) ()
77 (climi::with-transformed-position
((medium-transformation medium
) pm-x pm-y
)
78 (setf (slot-value climi
::graphic
'pm-x
) pm-x
79 (slot-value climi
::graphic
'pm-y
) pm-y
)
80 (values pm-x pm-y
(+ pm-x
(pixmap-width pixmap
)) (+ pm-y
(pixmap-height pixmap
)))))
82 (climi::def-graphic-op draw-pixmap
(pixmap pm-x pm-y
))
84 (defmethod medium-draw-pixmap* ((medium clim
:medium
) pixmap pm-x pm-y
)
85 (copy-from-pixmap pixmap
0 0 (pixmap-width pixmap
) (pixmap-height pixmap
)
88 (climi::defmethod
* (setf output-record-position
) :around
89 (nx ny
(record draw-pixmap-output-record
))
90 (climi::with-standard-rectangle
* (:x1 x1
:y1 y1
)
92 (with-slots (pm-x pm-y
)
101 (climi::defrecord-predicate draw-pixmap-output-record
(pm-x pm-y
)
102 (and (climi::if-supplied
(pm-x coordinate
)
103 (climi::coordinate
= (slot-value climi
::record
'pm-x
) pm-x
))
104 (climi::if-supplied
(pm-y coordinate
)
105 (climi::coordinate
= (slot-value climi
::record
'pm-y
) pm-y
))))
107 (defun draw-pixmap* (sheet pixmap x y
109 &key clipping-region transformation
)
110 (declare (ignore clipping-region transformation
))
111 (climi::with-medium-options
(sheet args
)
112 (medium-draw-pixmap* medium pixmap x y
)))
114 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
116 ;;; drawing functions
118 ;;; A staff step is half of the distance between two staff lines.
119 ;;; Given a staff-step value, determine the corresponding number of
120 ;;; pixels in the current font. The sign of the value returned is
121 ;;; the same as that of the argument.
122 ;;; But is that reasonable? It seems more logical to have it return
123 ;;; the opposite sign, so that the result from staff-step is always
124 ;;; added to some y coordinate.
125 (defun staff-step (n)
126 (* n
(/ (staff-line-distance *font
*) 2)))
128 ;;;;;;;;;;;;;;;;;; notehead
130 (define-presentation-type notehead
() :options
(name x staff-step
))
132 (defun draw-notehead (stream name x staff-step
)
133 (sdl::draw-shape stream
*font
*
135 ((:breve
:long
) :breve-notehead
)
136 (:whole
:whole-notehead
)
137 (:half
:half-notehead
)
138 (:filled
:filled-notehead
))
139 x
(staff-step (- staff-step
))))
141 (define-presentation-method present
142 (object (type notehead
) stream
(view score-view
) &key
)
143 (with-output-as-presentation (stream object
'notehead
)
144 (draw-notehead stream name x staff-step
)))
146 ;;;;;;;;;;;;;;;;;; accidental
148 (defun draw-accidental (stream name x staff-step
)
149 (sdl::draw-shape stream
*font
* name x
(staff-step (- staff-step
))))
151 ;;;;;;;;;;;;;;;;;; clef
153 (defun draw-clef (stream name x staff-step
)
154 (sdl::draw-shape stream
*font
*
156 ;; FIXME: while using the same glyph for :TREBLE
157 ;; and :TREBLE8 is fine from a musical point of
158 ;; view, some differentiation (by putting an
159 ;; italic 8 underneath, for instance) would be
161 ((:treble
:treble8
) :g-clef
)
164 x
(staff-step (- staff-step
))))
166 (define-presentation-type clef
() :options
(name x staff-step
))
168 (define-presentation-method present
169 (object (type clef
) stream
(view score-view
) &key
)
170 (with-output-as-presentation (stream object
'clef
)
171 (draw-clef stream name x staff-step
)))
173 ;;;;;;;;;;;;;;;;;; time signature
175 (defun draw-time-signature-component (stream component x
)
176 (flet ((component-name (c)
178 (1 :time-signature-1
)
179 (2 :time-signature-2
)
180 (3 :time-signature-3
)
181 (4 :time-signature-4
)
182 (5 :time-signature-5
)
183 (6 :time-signature-6
)
184 (7 :time-signature-7
)
185 (8 :time-signature-8
))))
188 (let* ((design (sdl::ensure-design
*font
* (component-name component
))))
189 (sdl::draw-shape stream
*font
* design x
(staff-step -
2))
190 (bounding-rectangle-width design
)))
191 ((cons (integer 1 8) (integer 1 8))
192 (destructuring-bind (num . den
) component
193 (let* ((num-name (component-name num
))
194 (den-name (component-name den
))
195 (ndesign (sdl::ensure-design
*font
* num-name
))
196 (ddesign (sdl::ensure-design
*font
* den-name
)))
197 (sdl::draw-shape stream
*font
* num-name x
(staff-step -
4))
198 (sdl::draw-shape stream
*font
* den-name x
(staff-step 0))
199 (max (bounding-rectangle-width ndesign
)
200 (bounding-rectangle-width ddesign
))))))))
202 ;;;;;;;;;;;;;;;;;; rest
204 (defun draw-rest (stream duration x staff-step
)
205 (sdl::draw-shape stream
*font
*
218 x
(staff-step (- staff-step
))))
220 ;;;;;;;;;;;;;;;;;; flags down
222 (defun draw-flags-down (stream nb x staff-step
)
223 (sdl::draw-shape stream
*font
*
230 x
(staff-step (- staff-step
))))
232 ;;;;;;;;;;;;;;;;;; flags up
234 (defun draw-flags-up (stream nb x staff-step
)
235 (sdl::draw-shape stream
*font
*
242 x
(staff-step (- staff-step
))))
244 ;;;;;;;;;;;;;;;;;; dot
246 (defun draw-dot (stream x staff-step
)
247 (sdl::draw-shape stream
*font
* :dot x
(staff-step (- staff-step
))))
249 ;;;;;;;;;;;;;;;;;; staff line
251 (defun draw-staff-line (pane x1 staff-step x2
)
252 (multiple-value-bind (down up
) (staff-line-offsets *font
*)
253 (let ((y1 (+ (- (staff-step staff-step
)) up
))
254 (y2 (+ (- (staff-step staff-step
)) down
)))
255 (draw-rectangle* pane x1 y1 x2 y2
))))
257 (defclass staff-output-record
(output-record)
258 ((parent :initarg
:parent
:initform nil
:accessor output-record-parent
)
259 (x :initarg
:x1
:initarg
:x-position
)
260 (y :initarg
:y1
:initarg
:y-position
)
261 (width :initarg
:width
)
262 (height :initarg height
)
263 (staff-lines :initform
'() :reader output-record-children
)))
265 (defmethod bounding-rectangle* ((record staff-output-record
))
266 (with-slots (x y width height
) record
267 (values x y
(+ x width
) (+ y height
))))
269 (defmethod output-record-position ((record staff-output-record
))
270 (with-slots (x y
) record
273 (defmethod (setf output-record-position
) (new-x new-y
(record staff-output-record
))
274 (with-slots (x y staff-lines
) record
275 (setf x new-x y new-y
)
276 (loop for staff-line in staff-lines
277 do
(multiple-value-bind (xx yy
) (output-record-position staff-line
)
278 (setf (output-record-position staff-line
)
279 (values (+ xx
(- new-x x
))
280 (+ yy
(- new-y y
))))))))
282 (defmethod output-record-start-cursor-position ((record staff-output-record
))
285 (defmethod (setf output-record-start-cursor-position
) (x y
(record staff-output-record
))
286 (declare (ignore x y
))
289 (defmethod output-record-end-cursor-position ((record staff-output-record
))
292 (defmethod (setf output-record-end-cursor-position
) (x y
(record staff-output-record
))
293 (declare (ignore x y
))
296 (defmethod output-record-hit-detection-rectangle* ((record staff-output-record
))
297 (bounding-rectangle* record
))
299 (defmethod output-record-refined-position-test ((record staff-output-record
) x y
)
300 (declare (ignore x y
))
303 ;;; remove this when McCLIM is fixed
304 (defmethod region-intersects-region-p (region (record staff-output-record
))
305 (with-bounding-rectangle* (x1 y1 x2 y2
) record
306 (region-intersects-region-p region
(make-rectangle* x1 y1 x2 y2
))))
308 (defmethod add-output-record (child (record staff-output-record
))
309 (push child
(slot-value record
'children
)))
311 (defmethod delete-output-record (child (record staff-output-record
) &optional
(errorp t
))
312 (with-slots (staff-lines) record
313 (when (and errorp
(not (member child staff-lines
:test
#'eq
)))
314 (error "not a child"))
315 (setf staff-lines
(delete child staff-lines
:test
#'eq
))))
317 (defmethod clear-output-record ((record staff-output-record
))
318 (setf (slot-value record
'staff-lines
) '()))
320 (defmethod output-record-count ((record staff-output-record
))
321 (length (slot-value record
'staff-lines
)))
323 (defmethod replay-output-record ((record staff-output-record
) stream
324 &optional
(region +everywhere
+)
325 (x-offset 0) (y-offset 0))
326 (loop for staff-line in
(slot-value record
'staff-lines
)
327 do
(replay-output-record staff-line stream region x-offset y-offset
)))
329 (define-presentation-type staff
() :options
(x1 x2
))
331 (define-presentation-type fiveline-staff
() :inherit-from
'staff
:options
(x1 x2
))
333 (defun draw-fiveline-staff (pane x1 x2
)
334 (multiple-value-bind (left right
) (bar-line-offsets *font
*)
335 (loop for staff-step from
0 by
2
337 do
(draw-staff-line pane
(+ x1 left
) staff-step
(+ x2 right
)))))
339 (define-presentation-method present
340 (object (type fiveline-staff
) stream
(view score-view
) &key
)
341 (with-output-as-presentation (stream object
'fiveline-staff
)
342 (draw-fiveline-staff stream x1 x2
)))
344 (define-presentation-type lyrics-staff
() :inherit-from
'staff
:options
(x1 x2
))
346 (defun draw-lyrics-staff (pane x1 x2
)
347 (declare (ignore x2
))
348 (multiple-value-bind (left right
) (bar-line-offsets *font
*)
349 (declare (ignore right
))
350 (draw-text* pane
"--" (+ x1 left
) 0)))
352 (define-presentation-method present
353 (object (type lyrics-staff
) stream
(view score-view
) &key
)
354 (with-output-as-presentation (stream object
'lyrics-staff
)
355 (draw-lyrics-staff stream x1 x2
)))
357 ;;;;;;;;;;;;;;;;;; stem
359 (defun draw-stem (pane x y1 y2
)
360 (multiple-value-bind (left right
) (stem-offsets *font
*)
361 (let ((x1 (+ x left
))
363 (draw-rectangle* pane x1 y1 x2 y2
))))
365 (defun draw-right-stem (pane x y1 y2
)
366 (multiple-value-bind (dx dy
) (notehead-right-offsets *font
*)
367 (draw-stem pane
(+ x dx
) (- y1 dy
) y2
)))
369 (defun draw-left-stem (pane x y1 y2
)
370 (multiple-value-bind (dx dy
) (notehead-left-offsets *font
*)
371 (draw-stem pane
(+ x dx
) (- y1 dy
) y2
)))
373 ;;;;;;;;;;;;;;;;;; ledger line
375 (defun draw-ledger-line (pane x staff-step
)
376 (multiple-value-bind (down up
) (ledger-line-y-offsets *font
*)
377 (multiple-value-bind (left right
) (ledger-line-x-offsets *font
*)
378 (let ((x1 (+ x left
))
379 (y1 (- (+ (staff-step staff-step
) down
)))
381 (y2 (- (+ (staff-step staff-step
) up
))))
382 (draw-rectangle* pane x1 y1 x2 y2
)))))
385 ;;;;;;;;;;;;;;;;;; bar line
387 (defun draw-bar-line (pane x y1 y2
)
388 (multiple-value-bind (left right
) (bar-line-offsets *font
*)
389 (let ((x1 (+ x left
))
391 ;; see comment in ROUND-COORDINATE in McCLIM's CLX backend
392 (draw-rectangle* pane
(floor (+ x1
0.5)) y1
(floor (+ x2
0.5)) y2
))))
394 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
398 (defclass beam-output-record
(score-output-record)
399 ((light-glyph-p :initarg
:light-glyph-p
)
400 (clipping-region :initarg
:clipping-region
)
401 (thickness :initarg
:thickness
)))
403 ;;; draw a horizontal beam around the vertical reference
405 (defun draw-horizontal-beam (medium x1 y x2
)
406 (multiple-value-bind (down up
) (beam-offsets *font
*)
407 (draw-rectangle* medium x1
(+ y up
) x2
(+ y down
))))
410 (defclass downward-beam-output-record
(beam-output-record)
413 (defmethod medium-draw-downward-beam* (medium x1 y1 x2 y2 thickness
)
414 (let ((inverse-slope (abs (/ (- x2 x1
) (- y2 y1
)))))
415 (loop for y from y1 below y2
416 for x from x1 by inverse-slope do
417 (let ((upper (sdl::ensure-beam-segment-design
:down
:upper
(- (round (+ x inverse-slope
)) (round x
))))
418 (upper-tr (make-translation-transformation (round x
) y
))
419 (lower (sdl::ensure-beam-segment-design
:down
:lower
(- (round (+ x inverse-slope
)) (round x
))))
420 (lower-tr (make-translation-transformation (round x
) (+ y thickness
))))
421 (climi::medium-draw-bezier-design
* medium
(transform-region upper-tr upper
))
422 (climi::medium-draw-bezier-design
* medium
(transform-region lower-tr lower
))
423 (medium-draw-rectangle* medium
(round x
) (1+ y
) (round (+ x inverse-slope
)) (+ y thickness
) t
)))))
425 (defmethod medium-draw-downward-beam*
426 ((medium clim-postscript
::postscript-medium
) x1 y1 x2 y2 thickness
)
427 (draw-polygon* (medium-sheet medium
) `(,x1
,y1
,x1
,(+ y1 thickness
) ,x2
,(+ y2 thickness
) ,x2
,y2
) :closed t
:filled t
))
429 (defmethod medium-draw-upward-beam* (medium x1 y1 x2 y2 thickness
)
430 (let ((inverse-slope (abs (/ (- x2 x1
) (- y2 y1
)))))
431 (loop for y from y1 above y2
432 for x from x1 by inverse-slope do
433 (let ((upper (sdl::ensure-beam-segment-design
:up
:upper
(- (round (+ x inverse-slope
)) (round x
))))
434 (upper-tr (make-translation-transformation (round x
) y
))
435 (lower (sdl::ensure-beam-segment-design
:up
:lower
(- (round (+ x inverse-slope
)) (round x
))))
436 (lower-tr (make-translation-transformation (round x
) (+ y thickness -
1))))
437 (climi::medium-draw-bezier-design
* medium
(transform-region upper-tr upper
))
438 (climi::medium-draw-bezier-design
* medium
(transform-region lower-tr lower
))
439 (medium-draw-rectangle* medium
(round x
) y
(round (+ x inverse-slope
)) (1- (+ y thickness
)) t
)))))
441 (defmethod medium-draw-upward-beam*
442 ((medium clim-postscript
::postscript-medium
) x1 y1 x2 y2 thickness
)
443 (draw-polygon* (medium-sheet medium
) `(,x1
,y1
,x1
,(+ y1 thickness
) ,x2
,(+ y2 thickness
) ,x2
,y2
) :closed t
:filled t
))
445 (defmethod replay-output-record ((record downward-beam-output-record
) stream
446 &optional
(region +everywhere
+)
447 (x-offset 0) (y-offset 0))
448 (declare (ignore x-offset y-offset region
))
449 (with-bounding-rectangle* (x1 y1 x2 y2
) record
450 (with-slots (thickness ink clipping-region
) record
451 (let ((medium (sheet-medium stream
)))
452 (with-drawing-options
453 (medium :ink ink
:clipping-region clipping-region
)
454 (medium-draw-downward-beam* medium x1 y1 x2
(- y2 thickness
) thickness
))))))
456 (defclass upward-beam-output-record
(beam-output-record)
459 (defmethod replay-output-record ((record upward-beam-output-record
) stream
460 &optional
(region +everywhere
+)
461 (x-offset 0) (y-offset 0))
462 (declare (ignore x-offset y-offset region
))
463 (with-bounding-rectangle* (x1 y1 x2 y2
) record
464 (with-slots (thickness ink clipping-region
) record
465 (let ((medium (sheet-medium stream
)))
466 (with-drawing-options
467 (medium :ink ink
:clipping-region clipping-region
)
468 (medium-draw-upward-beam* medium x1
(- y2 thickness
) x2 y1 thickness
))))))
470 (defun transform-beam-attributes (transformation x1 y1 x2 y2 down up thickness
)
471 (multiple-value-bind (xx1 yy1
)
472 (transform-position transformation x1 y1
)
473 (multiple-value-bind (xx2 yy2
)
474 (transform-position transformation x2 y2
)
475 (multiple-value-bind (xd yd
)
476 (transform-distance transformation
0 down
)
477 (declare (ignore xd
))
478 (multiple-value-bind (xu yu
)
479 (transform-distance transformation
0 up
)
480 (declare (ignore xu
))
481 (multiple-value-bind (xt yt
)
482 (transform-distance transformation
0 thickness
)
483 (declare (ignore xt
))
484 (values xx1 yy1 xx2 yy2 yd yu yt
)))))))
486 ;;; draw a sloped beam. The vertical reference points
487 ;;; of the two end points are indicated by y1 and y2.
488 (defun draw-sloped-beam (medium x1 y1 x2 y2
)
489 (multiple-value-bind (down up
) (beam-offsets *font
*)
490 (let ((transformation (medium-transformation (medium-sheet medium
)))
491 (thickness (- down up
)))
493 (when (stream-recording-p (medium-sheet medium
))
494 (multiple-value-bind (xx1 yy1 xx2 yy2 yd yu yt
)
495 (transform-beam-attributes transformation x1 y1 x2 y2
497 (stream-add-output-record
498 (medium-sheet medium
)
499 (make-instance 'downward-beam-output-record
500 :x1 xx1
:y1
(+ yy1 yu
) :x2 xx2
:y2
(+ yy2 yd
)
501 :thickness yt
:ink
(medium-ink medium
)
502 :clipping-region
(transform-region transformation
(medium-clipping-region medium
))))))
503 (when (stream-drawing-p (medium-sheet medium
))
504 (medium-draw-downward-beam* medium x1
(+ y1 up
) x2
(+ y2 up
) thickness
)))
506 (when (stream-recording-p (medium-sheet medium
))
507 (multiple-value-bind (xx1 yy1 xx2 yy2 yd yu yt
)
508 (transform-beam-attributes transformation x1 y1 x2 y2
510 (stream-add-output-record
511 (medium-sheet medium
)
512 (make-instance 'upward-beam-output-record
513 :x1 xx1
:y1
(+ yy2 yu
) :x2 xx2
:y2
(+ yy1 yd
)
514 :thickness yt
:ink
(medium-ink medium
)
515 :clipping-region
(transform-region transformation
(medium-clipping-region medium
))))))
516 (when (stream-drawing-p (medium-sheet medium
))
517 (medium-draw-upward-beam* medium x1
(+ y1 up
) x2
(+ y2 up
) thickness
)))))))
519 ;;; an offset of -1 means hang, 0 means straddle and 1 means sit
520 (defun draw-beam (pane x1 staff-step-1 offset1 x2 staff-step-2 offset2
)
522 (draw-beam pane x2 staff-step-2 offset2 x1 staff-step-1 offset1
)
523 (multiple-value-bind (left right
) (stem-offsets *font
*)
524 (let* ((xx1 (+ x1 left
))
526 (offset (beam-hang-sit-offset *font
*))
527 (y1 (- (+ (staff-step staff-step-1
) (* offset1 offset
))))
528 (y2 (- (+ (staff-step staff-step-2
) (* offset2 offset
))))
529 (medium (sheet-medium pane
)))
531 (draw-horizontal-beam pane xx1 y1 xx2
)
532 (draw-sloped-beam medium xx1 y1 xx2 y2
))))))
534 (defun draw-tie-up (pane x1 x2 staff-step
)
535 (let ((dist (/ (- x2 x1
) (staff-step 4/3))))
537 (let ((xx1 (round (+ x1
(staff-step 10))))
538 (xx2 (round (- x2
(staff-step 10))))
539 (y1 (- (round (staff-step (+ staff-step
11/3)))))
540 (thickness (round (staff-step 2/3))))
541 (sdl::draw-shape pane
*font
* :large-tie-up-left xx1
(staff-step (- staff-step
)))
542 (sdl::draw-shape pane
*font
* :large-tie-up-right xx2
(staff-step (- staff-step
)))
543 (draw-rectangle* pane xx1 y1 xx2
(+ y1 thickness
)))
544 (let ((glyph-name (cond ((> dist
18) :large-tie-10-up
)
545 ((> dist
17) :large-tie-9-up
)
546 ((> dist
16) :large-tie-8-up
)
547 ((> dist
15) :large-tie-7-up
)
548 ((> dist
14) :large-tie-6-up
)
549 ((> dist
13) :large-tie-5-up
)
550 ((> dist
12) :large-tie-4-up
)
551 ((> dist
11) :large-tie-3-up
)
552 ((> dist
10) :large-tie-2-up
)
553 ((> dist
9) :large-tie-1-up
)
554 ((> dist
8) :small-tie-8-up
)
555 ((> dist
7) :small-tie-7-up
)
556 ((> dist
6) :small-tie-6-up
)
557 ((> dist
5) :small-tie-5-up
)
558 ((> dist
4) :small-tie-4-up
)
559 ((> dist
3) :small-tie-3-up
)
560 ((> dist
2) :small-tie-2-up
)
561 (t :small-tie-1-up
))))
562 (sdl::draw-shape pane
*font
* glyph-name
563 (round (* 0.5 (+ x1 x2
))) (staff-step (- staff-step
)))))))
565 (defun draw-tie-down (pane x1 x2 staff-step
)
566 (let ((dist (/ (- x2 x1
) (staff-step 4/3))))
568 (let ((xx1 (round (+ x1
(staff-step 10))))
569 (xx2 (round (- x2
(staff-step 10))))
570 (y1 (- (round (staff-step (- staff-step
8/3)))))
571 (thickness (round (staff-step 2/3))))
572 (sdl::draw-shape pane
*font
* :large-tie-down-left xx1
(staff-step (- staff-step
)))
573 (sdl::draw-shape pane
*font
* :large-tie-down-right xx2
(staff-step (- staff-step
)))
574 (draw-rectangle* pane xx1 y1 xx2
(+ y1 thickness
)))
575 (let ((glyph-name (cond ((> dist
18) :large-tie-10-down
)
576 ((> dist
17) :large-tie-9-down
)
577 ((> dist
16) :large-tie-8-down
)
578 ((> dist
15) :large-tie-7-down
)
579 ((> dist
14) :large-tie-6-down
)
580 ((> dist
13) :large-tie-5-down
)
581 ((> dist
12) :large-tie-4-down
)
582 ((> dist
11) :large-tie-3-down
)
583 ((> dist
10) :large-tie-2-down
)
584 ((> dist
9) :large-tie-1-down
)
585 ((> dist
8) :small-tie-8-down
)
586 ((> dist
7) :small-tie-7-down
)
587 ((> dist
6) :small-tie-6-down
)
588 ((> dist
5) :small-tie-5-down
)
589 ((> dist
4) :small-tie-4-down
)
590 ((> dist
3) :small-tie-3-down
)
591 ((> dist
2) :small-tie-2-down
)
592 (t :small-tie-1-down
))))
593 (sdl::draw-shape pane
*font
* glyph-name
594 (round (* 0.5 (+ x1 x2
))) (staff-step (- staff-step
)))))))
596 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
598 ;;; convenience macros
600 (defmacro with-notehead-right-offsets
((right up
) &body body
)
601 `(multiple-value-bind (,right
,up
) (notehead-right-offsets *font
*)
604 (defmacro with-notehead-left-offsets
((left down
) &body body
)
605 `(multiple-value-bind (,left
,down
) (notehead-left-offsets *font
*)
608 (defmacro with-suspended-note-offset
(offset &body body
)
609 `(let ((,offset
(suspended-note-offset *font
*)))
612 (defmacro with-score-pane
(pane &body body
)
614 (clear-output-record (stream-output-history ,pane
))
617 (defmacro with-vertical-score-position
((pane yref
) &body body
)
618 `(with-translation (,pane
0 ,yref
)
621 (defmacro with-staff-size
(size &body body
)
622 (let ((size-var (gensym)))
623 `(let ((,size-var
,size
))
624 (unless (aref *fonts
* ,size-var
)
625 (setf (aref *fonts
* ,size-var
)
626 (make-font ,size-var
)))
627 (let ((*font
* (aref *fonts
* ,size-var
)))
630 (defmacro with-light-glyphs
(pane &body body
)
631 `(with-drawing-options (,pane
:ink
(light-glyphs-ink (stream-default-view ,pane
)))