source file of the GNU LilyPond music typesetter
- (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
Modified 2001--2002 by Rune Zedeler <rz@daimi.au.dk>
*/
#include "arpeggio.hh"
#include "context.hh"
#include "engraver.hh"
-#include "event.hh"
-#include "item.hh"
#include "protected-scm.hh"
#include "rhythmic-head.hh"
#include "side-position-interface.hh"
-#include "spanner.hh"
#include "tie.hh"
#include "warn.hh"
-
class Accidental_entry
{
public:
virtual void process_acknowledged_grobs ();
virtual void finalize ();
+ virtual void derived_mark () const;
public:
- Protected_scm last_keysig_; // ugh.
+ SCM last_keysig_; // ugh.
/* Urgh. Since the accidentals depend on lots of variables, we have
to store all information before we can really create the
set_property_on_children (Context *trans, char const *sym, SCM val)
{
trans->set_property (sym, ly_deep_copy (val));
- for (SCM p = trans->children_contexts (); ly_c_pair_p (p); p = ly_cdr (p))
+ for (SCM p = trans->children_contexts (); scm_is_pair (p); p = scm_cdr (p))
{
- Context *trg = unsmob_context (ly_car (p));
+ Context *trg = unsmob_context (scm_car (p));
set_property_on_children (trg, sym, ly_deep_copy (val));
}
}
last_keysig_ = SCM_EOL;
}
+void
+Accidental_engraver::derived_mark () const
+{
+ scm_gc_mark (last_keysig_);
+}
+
void
Accidental_engraver::update_local_key_signature ()
{
* Then check the global signature (only step).
Return number of accidentals (0, 1 or 2). */
+
+static bool
+recent_enough (int bar_number, SCM alteration_def, SCM laziness)
+{
+ if (scm_is_number (alteration_def)
+ || laziness == SCM_BOOL_T)
+ return true;
+
+ return (bar_number <= scm_to_int (scm_cdr (alteration_def)) + scm_to_int (laziness));
+}
+
+static int
+extract_alteration (SCM alteration_def)
+{
+ if (scm_is_number (alteration_def))
+ return scm_to_int (alteration_def);
+ else if (scm_is_pair (alteration_def))
+ return scm_to_int (scm_car (alteration_def));
+ else if (alteration_def == SCM_BOOL_F)
+ return 0;
+ else
+ assert (0);
+ return 0;
+}
+
+bool
+is_tied (SCM alteration_def)
+{
+ return (alteration_def == SCM_BOOL_T)
+ || (scm_is_pair (alteration_def) && scm_car (alteration_def) == SCM_BOOL_T);
+}
+
static int
number_accidentals_from_sig (bool *different, SCM sig, Pitch *pitch,
- int curbarnum, SCM laziness, bool ignore_octave)
+ int bar_number, SCM laziness, bool ignore_octave)
{
int n = pitch->get_notename ();
int o = pitch->get_octave ();
- int a = pitch->get_alteration ();
- SCM prev_alt = SCM_BOOL_F;
+ SCM previous_alteration = SCM_BOOL_F;
- if (!ignore_octave)
- {
- SCM prev_local
- = scm_assoc (scm_cons (scm_int2num (o), scm_int2num (n)), sig);
- if (ly_c_pair_p (prev_local))
- {
- if (ly_c_pair_p (ly_cdr (prev_local))
- && scm_is_number (laziness))
- {
- int barnum = scm_to_int (ly_cddr (prev_local));
-
- prev_local = scm_cons (ly_car (prev_local), ly_cadr (prev_local));
- if (curbarnum <= barnum + scm_to_int (laziness))
- prev_alt = prev_local;
- }
- }
+ SCM from_same_octave = ly_assoc_get (scm_cons (scm_int2num (o),
+ scm_int2num (n)), sig, SCM_BOOL_F);
+ SCM from_key_signature = ly_assoc_get (scm_int2num (n), sig, SCM_BOOL_F);
+ SCM from_other_octaves = SCM_BOOL_F;
+ for (SCM s = sig ; scm_is_pair (s); s = scm_cdr (s))
+ {
+ SCM entry = scm_car (s);
+ if (scm_is_pair (scm_car (entry))
+ && scm_cdar (entry) == scm_int2num (n))
+ from_other_octaves = scm_cdr (entry);
}
+
- if (prev_alt == SCM_BOOL_F)
- prev_alt = scm_assoc (scm_int2num (n), sig);
-
- prev_alt = (prev_alt == SCM_BOOL_F) ? scm_int2num (0) : ly_cdr (prev_alt);
-
- /* UGH. prev_acc can be #t in case of ties. What is this for? */
- int p = scm_is_number (prev_alt) ? scm_to_int (prev_alt) : 0;
-
- int num;
- if (a == p && scm_is_number (prev_alt))
- num = 0;
- else if ( (abs (a)<abs (p) || p*a<0) && a != 0 )
- num = 2;
+ if (from_same_octave != SCM_BOOL_F
+ && recent_enough (bar_number, from_same_octave, laziness))
+ {
+ previous_alteration = from_same_octave;
+ }
+ else if (ignore_octave
+ && from_other_octaves != SCM_BOOL_F
+ && recent_enough (bar_number, from_other_octaves, laziness))
+ {
+ previous_alteration = from_other_octaves;
+ }
+ else if (from_key_signature != SCM_BOOL_F)
+ {
+ previous_alteration = from_key_signature;
+ }
+
+ int num = 1;
+ if (is_tied (previous_alteration))
+ {
+ num = 1;
+ *different = true;
+ }
else
- num = 1;
-
- *different = (a != p);
+ {
+ int prev = extract_alteration (previous_alteration);
+ int alter = pitch->get_alteration ();
+
+ if (alter == prev)
+ num = 0;
+ else if ((abs (alter) < abs (prev) || prev*alter < 0) && alter != 0)
+ num = 2;
+ *different = (alter != prev);
+ }
return num;
}
static int
number_accidentals (bool *different,
Pitch *pitch, Context *origin,
- SCM accidentals, int curbarnum)
+ SCM accidentals, int bar_number)
{
int number = 0;
*different = false;
- if (ly_c_pair_p (accidentals) && !scm_is_symbol (ly_car (accidentals)))
+ if (scm_is_pair (accidentals) && !scm_is_symbol (scm_car (accidentals)))
warning (_f ("Accidental typesetting list must begin with context-name: %s",
- ly_scm2string (ly_car (accidentals)).to_str0 ()));
+ ly_scm2string (scm_car (accidentals)).to_str0 ()));
- for (; ly_c_pair_p (accidentals) && origin;
- accidentals = ly_cdr (accidentals))
+ for (; scm_is_pair (accidentals) && origin;
+ accidentals = scm_cdr (accidentals))
{
// If pair then it is a new accidentals typesetting rule to be checked
- SCM rule = ly_car (accidentals);
- if (ly_c_pair_p (rule))
+ SCM rule = scm_car (accidentals);
+ if (scm_is_pair (rule))
{
- SCM type = ly_car (rule);
- SCM laziness = ly_cdr (rule);
+ SCM type = scm_car (rule);
+ SCM laziness = scm_cdr (rule);
SCM localsig = origin->get_property ("localKeySignature");
bool same_octave_b =
{
bool d = false;
int n = number_accidentals_from_sig
- (&d, localsig, pitch, curbarnum, laziness, any_octave_b);
+ (&d, localsig, pitch, bar_number, laziness, any_octave_b);
*different = *different || d;
number = max (number, n);
}
int bn = robust_scm2int (barnum, 0);
- Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
+ Moment mp = robust_scm2moment (smp, Moment (0));
if (mp.main_part_ < Rational (0))
bn--;
Grob *a
= make_item_from_properties (accidentals_[i].origin_trans_,
ly_symbol2scm ("Accidental"),
- note->self_scm ());
+ note->self_scm (),
+ "Accidental"
+ );
a->set_parent (support, Y_AXIS);
if (!accidental_placement_)
update_local_key_signature ();
}
-ENTER_DESCRIPTION (Accidental_engraver,
+ADD_TRANSLATOR (Accidental_engraver,
"Make accidentals. "
"Catch note heads, ties and notices key-change events. "
"This engraver usually lives at Staff level, but "