[gsharp-cvs] CVS update: gsharp/drawing.lisp gsharp/sdl.lisp
Robert Strandh
rstrandh at common-lisp.net
Tue Nov 15 18:49:53 UTC 2005
Update of /project/gsharp/cvsroot/gsharp
In directory common-lisp.net:/tmp/cvs-serv19808
Modified Files:
drawing.lisp sdl.lisp
Log Message:
Added more comments in an attempt to improve maintainability. Plus, it
helps me understand what I meant when I initially wrote the code.
Date: Tue Nov 15 19:49:52 2005
Author: rstrandh
Index: gsharp/drawing.lisp
diff -u gsharp/drawing.lisp:1.19 gsharp/drawing.lisp:1.20
--- gsharp/drawing.lisp:1.19 Sat Nov 12 08:14:28 2005
+++ gsharp/drawing.lisp Tue Nov 15 19:49:52 2005
@@ -534,6 +534,16 @@
(defun element-has-suspended-notes (element)
(not (apply #'= (mapcar #'final-xposition (notes element)))))
+;;; table of x offsets (in staff steps) of accendentals.
+;;; The first index represents a notehead or a type of accidental.
+;;; The second index represents a type of accidentsl.
+;;; The third index is a vertical distance, measured in difference
+;;; in staff steps between the two.
+;;; The table entry gives how much the accidental represented by
+;;; the second parameter must be positioned to the left of the
+;;; first one.
+;;; Entries in the table are offset by 5 in the last dimension
+;;; so that vertical distances between -5 and 5 can be represented
(defparameter *accidental-offset*
;;; -5 -4 -3 -2 -1 0 1 2 3 4 5
#3A((( 0 0 0 3.5 3.5 3.5 3.5 3.5 3.5 1 0) ; notehead - dbl flat
@@ -567,6 +577,11 @@
( 0 2.8 2.8 2.8 2.8 2.8 2.8 2.8 2.8 2.8 0) ; dbl sharp - sharp
( 0 0 0 2.8 2.8 2.8 2.8 2.8 0 0 0)))) ; dbl sharp - dbl sharp
+;;; given 1) a type of accidental 2) its position (in staff steps) 3)
+;;; a type of accidental or a type of notehead, and 4) its position,
+;;; return the x offset of the first accidental, i.e., how many staff
+;;; steps to the left that it must be moved in order to avoid overlap
+;;; with the second one.
(defun accidental-distance (acc1 pos1 acc2 pos2)
(let ((dist (- pos2 pos1)))
(if (> (abs dist) 5)
@@ -587,6 +602,13 @@
(:double-sharp 4))
(+ dist 5)))))
+;;; given two notes (where the first one has an accidental, and the
+;;; second one may or may not have an accidental) and the conversion
+;;; factor between staff steps and x positions, compute the x offset
+;;; of the accidental of the first note. If the second note has
+;;; an accidental, but that has not been given a final x offset, then
+;;; use the x offset of the notehead instead.
+;;; (this funtction should probably be renamed accidental-xoffset)
(defun accidental-xpos (note1 note2 staff-step)
(let* ((acc1 (final-accidental note1))
(pos1 (note-position note1))
@@ -599,9 +621,18 @@
(final-xposition note2))))
(- xpos2 (* staff-step (accidental-distance acc1 pos1 acc2 pos2)))))
+;;; given a note and a list of notes, compute x offset of the accidental
+;;; of the note as required by each of the notes in the list. In order
+;;; for the accidental of the note not to overlap any of the others,
+;;; we must use the minimum of all the x offsets thus computed.
+;;; (this function shoudl probably be renamed accidental-min-xoffset)
(defun accidental-min-xpos (note1 notes staff-step)
(reduce #'min notes :key (lambda (note) (accidental-xpos note1 note staff-step))))
+;;; given a list of notes that have accidentals to place, and a list of
+;;; notes that either have no accidentals or with already-placed accidentals,
+;;; compute the note in the first list that can be placed as far to the right
+;;; as possible.
(defun best-accidental (notes-with-accidentals notes staff-step)
(reduce (lambda (note1 note2) (if (>= (accidental-min-xpos note1 notes staff-step)
(accidental-min-xpos note2 notes staff-step))
@@ -609,14 +640,20 @@
note2))
notes-with-accidentals))
+;;; for each note in a list of notes, if it has an accidental, compute
+;;; the position of that accidental and store it in the note.
(defun compute-final-accidental-positions (notes x final-stem-direction)
(let* ((staff-step (score-pane:staff-step 1))
+ ;; sort the notes from top to bottom
(notes (sort (copy-list notes)
(lambda (x y) (> (note-position x) (note-position y)))))
(notes-with-accidentals (remove-if-not #'final-accidental notes)))
;; initially, no accidental has been placed
(loop for note in notes do (setf (accidental-position note) nil))
(when (eq final-stem-direction :up)
+ ;; when the stem direction is :up and there is a suspended note
+ ;; i.e., one to the right of the stem, then the accidental of the topmost
+ ;; suspended note is placed first.
(let ((first-suspended-note
(find x notes-with-accidentals :test #'/= :key #'final-xposition)))
(when first-suspended-note
@@ -641,6 +678,16 @@
(setf notes (remove (staff (car notes)) notes :test #'eq :key #'staff)))
groups))
+;;; draw a cluster. The stem direction and the stem position have
+;;; already been computed.
+;;; 1. Group notes by staff.
+;;; 2. Determine which notes in each group go to the left and which notes
+;;; go to the right of the stem.
+;;; 3. Determine which notes in each group should be displayed with an accidental.
+;;; 4. Compute the x offset of each accidental to be displayed.
+;;; 5. Draw the notes in each group
+;;; 6. If necessary, draw ledger lines for notes in a group
+;;; 7. Draw the stem, if any
(defmethod draw-element (pane (element cluster) x &optional (flags t))
(when (notes element)
(let ((direction (final-stem-direction element))
Index: gsharp/sdl.lisp
diff -u gsharp/sdl.lisp:1.11 gsharp/sdl.lisp:1.12
--- gsharp/sdl.lisp:1.11 Mon Nov 14 23:52:13 2005
+++ gsharp/sdl.lisp Tue Nov 15 19:49:52 2005
@@ -110,6 +110,9 @@
(declare (ignore initargs))
(with-slots (gf-char x-offset y-offset) glyph
(setf x-offset (floor (gf-char-min-m gf-char) 4)
+ ;; adding 1 to gv-char-max-n is necessary because
+ ;; of a discrepancy between the GF documentation
+ ;; and the GF file format
y-offset (- (ceiling (1+ (gf-char-max-n gf-char)) 4)))))
(defmethod glyph ((font font) glyph-no)
@@ -117,6 +120,9 @@
(let ((left (floor (gf-char-min-m gf-char) 4))
(right (ceiling (1+ (gf-char-max-m gf-char)) 4))
(down (floor (gf-char-min-n gf-char) 4))
+ ;; adding 1 to gv-char-max-n is necessary because
+ ;; of a discrepancy between the GF documentation
+ ;; and the GF file format
(up (ceiling (1+ (gf-char-max-n gf-char)) 4))
(matrix (gf-char-matrix gf-char)))
(unless pixmap
More information about the Gsharp-cvs
mailing list