Update of /project/gsharp/cvsroot/gsharp In directory clnet:/tmp/cvs-serv26132
Modified Files: gui.lisp measure.lisp Log Message: Better final accidentals:
* look back through the current bar / layer, no further than the currently active key signature, to find a note on the same staff with the same pitch: if there is one, and the accidentals are the same, no need to have an accidental displayed.
Remaining to do:
* more or less any editing action should invalidate the already-computed final accidentals of the current bar. At present, final accidentals aren't recomputed often enough.
--- /project/gsharp/cvsroot/gsharp/gui.lisp 2007/08/07 11:06:09 1.82 +++ /project/gsharp/cvsroot/gsharp/gui.lisp 2007/08/07 14:00:09 1.83 @@ -967,6 +967,11 @@ ;; does THING start before the temporal position denoted by BAR and ;; ELEMENT-OR-NIL? (assert (or (null element-or-nil) (eq (bar element-or-nil) bar))) + (when (null (bar thing)) + ;; THING is probably the key signature at the start of the piece, + ;; in which case it is definitely before whatever else happens. + (assert (typep thing 'key-signature)) + (return-from starts-before-p t)) (let ((barno (number bar))) (cond ((> (number (bar thing)) barno) nil) --- /project/gsharp/cvsroot/gsharp/measure.lisp 2007/07/18 07:51:54 1.35 +++ /project/gsharp/cvsroot/gsharp/measure.lisp 2007/08/07 14:00:09 1.36 @@ -237,14 +237,40 @@ ;; otherwise, give up for this note (t (setf (final-absolute-dot-ypos note) nil)))))))
+(defun find-prevailing-accidental (note) + (let* ((cluster (cluster note)) + ;; KLUDGE: This computation looks at the current layer's + ;; elements, and the note's key signature. While it's + ;; arguably right (in that accidentals in one layer don't + ;; affect accidentals in another) it's only arguable, and it + ;; would be nice if it weren't so unbelievably hard to do it + ;; the other way. + (bar (bar cluster)) + ;; FIXME: I can never remember how to access bar elements + ;; nicely, and here we need to access them in reverse + ;; order... + (index (position cluster (elements bar))) + (keysig (keysig note))) + (assert index) + (loop for i downfrom (1- index) to 0 + for element = (elt (elements bar) i) + while (gsharp::starts-before-p keysig bar element) + do (typecase element + (cluster + (loop for n in (notes element) + when (and (eq (staff n) (staff note)) + (= (pitch n) (pitch note))) + do (return-from find-prevailing-accidental + (accidentals n)))))) + (aref (alterations keysig) (mod (pitch note) 7)))) + ;;; 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. (defun compute-final-accidentals (group) (loop for note in group do (setf (final-accidental note) - (if (eq (accidentals note) - (aref (alterations (keysig note)) (mod (pitch note) 7))) + (if (eq (accidentals note) (find-prevailing-accidental note)) nil (accidentals note)))))