Update of /project/gsharp/cvsroot/gsharp In directory clnet:/tmp/cvs-serv21067
Modified Files: drawing.lisp measure.lisp packages.lisp Log Message: Dots!
Specifically, augmentation dots. Get their x- and y- positions more right, which sometimes entails not drawing a dot at all, sometimes adjusting the position for a dot downwards, and (when a flag is drawn or there is a suspended note in a flag-up situation) involves shifting the entire column of dots rightwards.
Add an example score full of things we got wrong.
--- /project/gsharp/cvsroot/gsharp/drawing.lisp 2006/06/19 17:40:34 1.71 +++ /project/gsharp/cvsroot/gsharp/drawing.lisp 2006/06/21 16:31:54 1.72 @@ -76,6 +76,9 @@ (defun final-absolute-accidental-xoffset (note) (+ (final-absolute-element-xoffset (cluster note)) (final-relative-accidental-xoffset note)))
+(defun final-absolute-dot-xoffset (cluster) + (+ (final-absolute-element-xoffset cluster) (score-pane:staff-step (final-relative-dot-xoffset cluster)))) + (defvar *cursor* nil)
;;; Compute the elasticity of each timeline in each measure of the @@ -832,9 +835,13 @@ (loop for pos from -2 downto bot-note-pos by 2 do (score-pane:draw-ledger-line pane x pos)))))
-(defun draw-flags (pane element x direction pos) +(defun flags-drawn-p (element) (let ((nb (max (rbeams element) (lbeams element)))) - (when (and (> nb 0) (eq (notehead element) :filled)) + (and (> nb 0) (eq (notehead element) :filled) nb))) + +(defun draw-flags (pane element x direction pos) + (let ((nb (flags-drawn-p element))) + (when nb (if (eq direction :up) (score-pane:with-notehead-right-offsets (right up) (declare (ignore up)) @@ -843,23 +850,23 @@ (declare (ignore down)) (score-pane:draw-flags-up pane nb (+ x left) pos))))))
-(defun draw-dots (pane nb-dots x pos) - (let ((staff-step (score-pane:staff-step 1))) - (loop with dotpos = (if (evenp pos) (1+ pos) pos) - repeat nb-dots - for xx from (+ x (* 2 staff-step)) by staff-step do - (score-pane:draw-dot pane xx dotpos)))) +(defun draw-dots (pane nb-dots x dot-xoffset dot-pos) + (when dot-pos + (let ((staff-step (score-pane:staff-step 1))) + (loop repeat nb-dots + for xx from dot-xoffset by staff-step do + (score-pane:draw-dot pane xx dot-pos)))))
-(defun draw-note (pane note notehead nb-dots x pos) +(defun draw-note (pane note notehead nb-dots x pos dot-xoffset dot-pos) (score-pane:with-vertical-score-position (pane (staff-yoffset (staff note))) (score-pane:draw-notehead pane notehead x pos) (when (final-accidental note) (score-pane:draw-accidental pane (final-accidental note) (final-absolute-accidental-xoffset note) pos)) - (draw-dots pane nb-dots x pos))) + (draw-dots pane nb-dots x dot-xoffset dot-pos)))
-(defun draw-notes (pane notes dots notehead) +(defun draw-notes (pane notes dots notehead dot-xoffset) (loop for note in notes do - (draw-note pane note notehead dots (final-absolute-note-xoffset note) (note-position note)))) + (draw-note pane note notehead dots (final-absolute-note-xoffset note) (note-position note) dot-xoffset (final-absolute-dot-ypos note))))
(defun element-has-suspended-notes (element) (not (apply #'= (mapcar #'final-relative-note-xoffset (notes element))))) @@ -873,17 +880,23 @@ (defmethod draw-element (pane (element cluster) &optional (flags t)) (with-new-output-record (pane) (unless (null (notes element)) - (let ((direction (final-stem-direction element)) - (stem-pos (final-stem-position element)) - (stem-yoffset (final-stem-yoffset element)) - (groups (group-notes-by-staff (notes element))) - (x (final-absolute-element-xoffset element))) + (let* ((direction (final-stem-direction element)) + (stem-pos (final-stem-position element)) + (stem-yoffset (final-stem-yoffset element)) + (groups (group-notes-by-staff (notes element))) + (x (final-absolute-element-xoffset element)) + (dot-xoffset + (let ((basic-xoffset (+ (score-pane:staff-step 2) + (reduce #'max (mapcar #'final-absolute-note-xoffset (notes element)))))) + (if (and flags (eq direction :up) (flags-drawn-p element)) + (max basic-xoffset (+ (score-pane:staff-step 4) x)) + basic-xoffset)))) (when flags (score-pane:with-vertical-score-position (pane stem-yoffset) (draw-flags pane element x direction stem-pos))) - (loop for group in groups do - (draw-notes pane group (dots element) (notehead element)) - (draw-ledger-lines pane x group)) + (loop for group in groups do + (draw-notes pane group (dots element) (notehead element) dot-xoffset) + (draw-ledger-lines pane x group)) (unless (eq (notehead element) :whole) (if (eq direction :up) (score-pane:draw-right-stem --- /project/gsharp/cvsroot/gsharp/measure.lisp 2006/06/19 17:40:34 1.31 +++ /project/gsharp/cvsroot/gsharp/measure.lisp 2006/06/21 16:31:54 1.32 @@ -56,7 +56,11 @@ :accessor final-relative-accidental-xoffset) (final-accidental :initform nil :accessor final-accidental) ;; the relative x offset of the note with respect to the cluster - (final-relative-note-xoffset :accessor final-relative-note-xoffset))) + (final-relative-note-xoffset :accessor final-relative-note-xoffset) + ;; the absolute y position of any dot, or NIL if dots should not be + ;; drawn + (final-absolute-dot-ypos :accessor final-absolute-dot-ypos :initform nil) +))
;;; given a list of notes, group them so that every note in the group ;;; is displayed on the same staff. Return the list of groups. @@ -158,7 +162,7 @@
(define-added-mixin rcluster () cluster ((final-stem-direction :accessor final-stem-direction) - ;; the position, in staff steps, of the top not in the element. + ;; the position, in staff steps, of the top note in the element. (top-note-pos :accessor top-note-pos) ;; the position, in staff steps, of the bottom note in the element. (bot-note-pos :accessor bot-note-pos))) @@ -217,6 +221,22 @@ when (non-empty-cluster-p element) do (setf (final-stem-direction element) stem-direction))))
+(defun compute-final-dot-positions (group) + (setf group (sort (copy-list group) #'> :key #'note-position)) + (let ((so-far nil)) + (dolist (note group) + (let* ((position (note-position note)) + (ideal (if (oddp position) position (1+ position)))) + (cond + ;; if there's no dot at our ideal position, use that + ((not (member ideal so-far)) (push (setf (final-absolute-dot-ypos note) ideal) so-far)) + ;; if the note in question is on a line and we haven't + ;; got a dot in the space underneath, use that + ((and (evenp position) (not (member (- ideal 2) so-far))) + (push (setf (final-absolute-dot-ypos note) (- ideal 2)) so-far)) + ;; otherwise, give up for this note + (t (setf (final-absolute-dot-ypos note) nil))))))) + ;;; Given a list of notes to be displayed on the same staff line, for ;;; each note, compute the accidental to be displayed as a function of ;;; the accidentals of the note and the key signature of the staff. @@ -550,6 +570,7 @@
(defun compute-staff-group-parameters (staff-group stem-direction) (compute-final-relative-note-xoffsets staff-group stem-direction) + (compute-final-dot-positions staff-group) (compute-final-accidentals staff-group) (compute-final-relative-accidental-xoffset staff-group stem-direction))
@@ -622,7 +643,7 @@
(defmethod compute-bar-parameters ((bar melody-bar)) (loop for group in (beam-groups (elements bar)) - do (compute-beam-group-parameters group))) + do (compute-beam-group-parameters group)))
;;; From a list of simultaneous bars (and some other stuff), create a ;;; measure. The `other stuff' is the spacing style, which is needed --- /project/gsharp/cvsroot/gsharp/packages.lisp 2006/06/14 03:38:56 1.57 +++ /project/gsharp/cvsroot/gsharp/packages.lisp 2006/06/21 16:31:54 1.58 @@ -128,6 +128,7 @@ #:beam-groups #:final-stem-direction #:group-notes-by-staff #:final-relative-note-xoffset #:final-accidental #:final-relative-accidental-xoffset + #:final-relative-dot-xoffset #:final-absolute-dot-ypos #:timeline #:timelines #:elasticity #:smallest-gap #:elasticity-function))