--- /dev/null
+%non of the dynamics properties work anymore
+
+\score {
+ \context Voice \notes\relative c {
+% \property Voice.verticalDirection = #-1
+
+ \property Voice.dynamicDirection = #1
+ \property Voice.dynamicPadding = #40
+ c \p c \< \! c \ff\> c \!c-\p
+
+ }
+}
%
\score{
\notes\relative c''{
- %\property Staff.textEmptyDimension=1
- a-"This text has no"
- a
- a
- a-"width; the default"
- \break
\property Staff.textNonEmpty=##t
- %\property Staff.textEmptyDimension=0
- a-"This text"
- a-"is fat: notes are spaced"
- a-"far apart and text"
- a-"does not collide"
+ c4_"longlonglonglonglonglong" c4_"text"
}
\paper{
- linewidth=80.\mm;
+ linewidth=-80.\mm;
}
}
--- /dev/null
+\score{
+ \context Staff = first <
+ \context Voice=first { \skip 1; }
+ \context Voice=second { \skip 1; }
+
+ \context Voice=first \partcombine Voice
+ \context Thread=first \notes\relative c''
+ {
+ c4 d e f
+ b,4 d c d
+ r2 e4 f
+ c4 d e f
+ }
+ \context Thread=second \notes\relative c''
+ {
+ a b c d
+ r2 c4 d
+ a c c d
+ a4. b8 c4 d
+ }
+ >
+}
--- /dev/null
+/*
+ a2-devnull-engraver.cc -- implement A2_devnull_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#include "engraver.hh"
+#include "item.hh"
+#include "musical-request.hh"
+#include "translator-group.hh"
+
+class A2_devnull_engraver : public Engraver
+{
+public:
+ VIRTUAL_COPY_CONS (Translator);
+
+protected:
+ virtual bool do_try_music (Music*);
+};
+
+ADD_THIS_TRANSLATOR (A2_devnull_engraver);
+
+bool
+A2_devnull_engraver::do_try_music (Music *m)
+{
+ if (Note_req * n = dynamic_cast <Note_req *> (m))
+ {
+ SCM a2 = get_property ("a2");
+ // should be able to read id_str_, no?
+ SCM second = get_property ("second");
+
+ if (a2 == SCM_BOOL_T && second == SCM_BOOL_T)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
--- /dev/null
+/*
+ a2-engraver.cc -- implement A2_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#include "engraver.hh"
+#include "item.hh"
+#include "note-head.hh"
+#include "stem.hh"
+#include "translator-group.hh"
+#include "side-position-interface.hh"
+#include "directional-element-interface.hh"
+
+class A2_engraver : public Engraver
+{
+public:
+ A2_engraver ();
+ VIRTUAL_COPY_CONS (Translator);
+
+protected:
+ virtual void do_process_music ();
+ virtual void acknowledge_element (Score_element_info);
+ //virtual void process_acknowledged ();
+
+ virtual void do_pre_move_processing ();
+
+private:
+ Item* text_p_;
+};
+
+ADD_THIS_TRANSLATOR (A2_engraver);
+
+A2_engraver::A2_engraver ()
+{
+ text_p_ = 0;
+}
+
+void
+A2_engraver::do_process_music ()
+{
+ if (!text_p_)
+ {
+ SCM a2 = get_property ("a2");
+ SCM solo = get_property ("solo");
+ SCM solo2 = get_property ("solo2");
+
+ if (solo == SCM_BOOL_T || a2 == SCM_BOOL_T || solo2 == SCM_BOOL_T)
+ {
+ text_p_ = new Item (get_property ("basicTextScriptProperties"));
+ Side_position::set_axis (text_p_, Y_AXIS);
+ announce_element (text_p_, 0);
+
+ /*
+ Urg, read prop
+ */
+ SCM text;
+ Direction dir = UP;
+ if (solo == SCM_BOOL_T)
+ {
+ text = ly_str02scm ("Solo");
+ }
+ else if (solo2 == SCM_BOOL_T)
+ {
+ text = ly_str02scm ("Solo II");
+ dir = DOWN;
+ }
+ else if (a2 == SCM_BOOL_T)
+ {
+ text = ly_str02scm ("\\`a 2");
+ }
+
+ Side_position::set_direction (text_p_, dir);
+ text_p_->set_elt_property ("text", text);
+
+ }
+ }
+}
+
+void
+A2_engraver::acknowledge_element (Score_element_info i)
+{
+ if (text_p_)
+ {
+ if (Note_head::has_interface (i.elem_l_))
+ {
+ Score_element*t = text_p_;
+ Side_position::add_support (t, i.elem_l_);
+ if (Side_position::get_axis (t) == X_AXIS
+ && !t->parent_l (Y_AXIS))
+ t->set_parent (i.elem_l_, Y_AXIS);
+ }
+ if (Stem::has_interface (i.elem_l_))
+ {
+ Side_position::add_support (text_p_, i.elem_l_);
+
+ SCM a2 = get_property ("a2");
+ SCM solo = get_property ("solo");
+ SCM solo2 = get_property ("solo2");
+
+ SCM first = get_property ("first");
+ SCM second = get_property ("second");
+
+ if (solo != SCM_BOOL_T
+ && solo2 != SCM_BOOL_T
+ && a2 != SCM_BOOL_T)
+ {
+ if (first == SCM_BOOL_T)
+ {
+ Directional_element_interface (i.elem_l_).set (UP);
+ }
+ else if (second == SCM_BOOL_T)
+ {
+ Directional_element_interface (i.elem_l_).set (DOWN);
+ }
+ }
+ }
+ }
+}
+
+void
+A2_engraver::do_pre_move_processing ()
+{
+ if (text_p_)
+ {
+ Side_position::add_staff_support (text_p_);
+ typeset_element (text_p_);
+ text_p_ = 0;
+ }
+ // burp: reset properties
+ daddy_trans_l_->set_property ("a2", SCM_BOOL_F);
+ daddy_trans_l_->set_property ("solo", SCM_BOOL_F);
+ daddy_trans_l_->set_property ("solo2", SCM_BOOL_F);
+}
+
virtual void acknowledge_element (Score_element_info);
virtual void process_acknowledged ();
virtual Spanner* get_spanner_p () const;
+ virtual void add_element (Score_element*) ;
public:
+
VIRTUAL_COPY_CONS(Translator);
Axis_group_engraver ();
};
if ((!par || !Axis_group_interface::has_interface (par))
&& ! elts_[i]->empty_b (Y_AXIS))
- Axis_group_interface::add_element (staffline_p_, elts_[i]);
+ add_element (elts_[i]);
}
elts_.clear ();
}
+void
+Axis_group_engraver::add_element (Score_element*e)
+{
+ Axis_group_interface::add_element (staffline_p_, e);
+}
////////////////////////////////////////////////////////
protected:
virtual Spanner*get_spanner_p ()const;
virtual void acknowledge_element (Score_element_info);
+ virtual void add_element (Score_element *e);
public:
VIRTUAL_COPY_CONS(Translator);
};
+void
+Hara_kiri_engraver::add_element (Score_element*e)
+{
+ Hara_kiri_group_spanner::add_element (staffline_p_, e);
+}
+
+
Spanner*
Hara_kiri_engraver::get_spanner_p () const
{
(c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
-
+#include "hara-kiri-group-spanner.hh"
#include "axis-group-interface.hh"
#include "score-element.hh"
bool
Axis_group_interface::axis_b (Score_element*me,Axis a )
{
- return me->has_extent_callback_b (group_extent_callback, a);
+ /*
+ urg. FIXME, check for Hara_kiri_group_spanner shouldn't be necessary?
+
+
+ */
+ return me->has_extent_callback_b (group_extent_callback, a) ||
+ (me->has_extent_callback_b (Hara_kiri_group_spanner::y_extent, a));
}
Interval
if (a1 != Y_AXIS && a2 != Y_AXIS)
me->set_extent_callback (0, Y_AXIS);
- me->set_extent_callback (Axis_group_interface::group_extent_callback,a1);
- me->set_extent_callback (Axis_group_interface::group_extent_callback,a2);
+ // if (!me->has_extent_callback_b (a1))
+ if (me->has_extent_callback_b (Score_element::molecule_extent, a1))
+ me->set_extent_callback (Axis_group_interface::group_extent_callback,a1);
+ if (me->has_extent_callback_b (Score_element::molecule_extent, a2))
+ me->set_extent_callback (Axis_group_interface::group_extent_callback,a2);
}
Link_array<Score_element>
{
String str =ly_scm2string (s);
SCM siz = gh_call1 (barsiz_proc, me->self_scm ());
- return compound_barline (me, str, gh_scm2double (siz)).create_scheme ();
+ Real sz = gh_scm2double (siz);
+ if (sz < 0)
+ return SCM_EOL;
+
+ return compound_barline (me, str, sz).create_scheme ();
}
return SCM_EOL;
}
me->set_elt_property ("items-worth-living", SCM_EOL);
me->add_offset_callback (force_hara_kiri_callback, Y_AXIS);
me->set_interface (ly_symbol2scm ("hara-kiri-spanner-interface"));
+ me->set_extent_callback (Hara_kiri_group_spanner::y_extent, Y_AXIS);
}
+Interval
+Hara_kiri_group_spanner::y_extent(Score_element*me, Axis a)
+{
+ assert (a == Y_AXIS);
+ consider_suicide (me);
+ return Axis_group_interface::group_extent_callback (me, a);
+}
+
+
bool
Hara_kiri_group_spanner::has_interface (Score_element*me)
{
return 0.0;
}
+
+Real
+Hara_kiri_group_spanner::force_hara_kiri_in_parent_callback (Score_element*daughter, Axis a)
+{
+ assert (a == Y_AXIS);
+ force_hara_kiri_callback (daughter->parent_l (a), Y_AXIS);
+ return 0.0;
+}
+
+void
+Hara_kiri_group_spanner::add_element (Score_element * me, Score_element *e)
+{
+ // e->add_offset_callback (force_hara_kiri_in_parent_callback, Y_AXIS);
+ Axis_group_interface::add_element (me, e);
+}
items-worth-living -- list of interesting items. If empty in a particular system,
clear this line
+
+ todo: naming
*/
class Hara_kiri_group_spanner
{
public:
static Real force_hara_kiri_callback (Score_element * , Axis);
+ static Interval y_extent (Score_element * , Axis);
+ static Real force_hara_kiri_in_parent_callback (Score_element * , Axis);
+ static void add_element (Score_element *me, Score_element *e);
static void set_interface (Score_element*me);
static bool has_interface (Score_element*);
static void consider_suicide (Score_element*me);
--- /dev/null
+/*
+ part-combine-music-iterator.hh -- declare Part_combine_music_iterator
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+
+#ifndef PART_COMBINE_MUSIC_ITERATOR_HH
+#define PART_COMBINE_MUSIC_ITERATOR_HH
+
+#include "music-iterator.hh"
+
+class Part_combine_music_iterator : public Music_iterator
+{
+public:
+ Part_combine_music_iterator ();
+
+protected:
+ virtual void construct_children ();
+ virtual Moment next_moment () const;
+ virtual void do_process_and_next (Moment);
+ virtual Music_iterator *try_music_in_children (Music *) const;
+
+ virtual bool ok () const;
+ virtual void do_print () const;
+ virtual ~Part_combine_music_iterator ();
+
+private:
+ void change_to (Music_iterator*, String, String);
+
+ Music_iterator * first_iter_p_;
+ Music_iterator * second_iter_p_;
+
+ bool combined_b_;
+};
+
+#endif /* PART_COMBINE_MUSIC_ITERATOR_HH */
+
--- /dev/null
+/*
+ part-combine-music.hh -- declare Part_combine_music
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+
+#ifndef PART_COMBINE_MUSIC_HH
+#define PART_COMBINE_MUSIC_HH
+
+#include "music.hh"
+
+
+class Part_combine_music : public Music
+{
+public:
+ VIRTUAL_COPY_CONS (Music);
+ Part_combine_music (String, Music*, Music*);
+
+ Music * first_l () const;
+ Music * second_l () const;
+
+ virtual void transpose (Musical_pitch);
+ virtual void do_print () const;
+ virtual Moment length_mom () const;
+ virtual Musical_pitch to_relative_octave (Musical_pitch);
+ virtual void compress (Moment);
+
+ String what_str_;
+};
+
+#endif /* PART_COMBINE_MUSIC_HH */
+
Score_element*common_refpoint (Score_element const* s, Axis a) const;
Score_element*common_refpoint (SCM elt_list, Axis a) const;
+ // duh. slim down interface here. (todo)
bool has_offset_callback_b (Offset_callback, Axis)const;
void add_offset_callback (Offset_callback, Axis);
bool has_extent_callback_b (Extent_callback, Axis)const;
+ bool has_extent_callback_b (Axis) const;
void set_extent_callback (Extent_callback , Axis);
/**
#include "lyric-combine-music-iterator.hh"
#include "auto-change-music.hh"
#include "auto-change-iterator.hh"
+#include "part-combine-music.hh"
+#include "part-combine-music-iterator.hh"
#include "request.hh"
#include "request-iterator.hh"
#include "output-property.hh"
p = new Grace_iterator;
else if (dynamic_cast<Auto_change_music *> (m))
p = new Auto_change_iterator;
+ else if (dynamic_cast<Part_combine_music *> (m))
+ p = new Part_combine_music_iterator;
else if (dynamic_cast<Music_wrapper *> (m))
p = new Music_wrapper_iterator;
else if (Repeated_music * n = dynamic_cast<Repeated_music *> (m))
{"remove", REMOVE},
{"repeat", REPEAT},
{"addlyrics", ADDLYRICS},
+ {"partcombine", PARTCOMBINE},
{"score", SCORE},
{"script", SCRIPT},
{"skip", SKIP},
#include "mudela-version.hh"
#include "grace-music.hh"
#include "auto-change-music.hh"
+#include "part-combine-music.hh"
#include "output-property.hh"
bool
%token REMOVE
%token REPEAT
%token ADDLYRICS
+%token PARTCOMBINE
%token SCM_T
%token SCORE
%token SCRIPT
%type <scm> embedded_scm scalar
%type <music> Music Sequential_music Simultaneous_music Music_sequence
-%type <music> relative_music re_rhythmed_music
+%type <music> relative_music re_rhythmed_music part_combined_music
%type <music> property_def translator_change
%type <scm> Music_list
%type <outputdef> music_output_def_body
}
| relative_music { $$ = $1; }
| re_rhythmed_music { $$ = $1; }
+ | part_combined_music { $$ = $1; }
;
relative_music:
}
;
+part_combined_music:
+ PARTCOMBINE STRING Music Music {
+ Part_combine_music * p = new Part_combine_music (ly_scm2string ($2), $3, $4);
+ $$ = p;
+ }
+ ;
+
translator_change:
TRANSLATOR STRING '=' STRING {
Change_translator * t = new Change_translator;
--- /dev/null
+/*
+ part-combine-music-iterator.cc -- implement Part_combine_music_iterator
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
+ */
+
+#include "part-combine-music.hh"
+#include "part-combine-music-iterator.hh"
+#include "translator-group.hh"
+#include "musical-request.hh"
+#include "warn.hh"
+
+Part_combine_music_iterator::Part_combine_music_iterator ()
+{
+ combined_b_ = false;
+
+ first_iter_p_ = 0;
+ second_iter_p_ = 0;
+}
+
+Part_combine_music_iterator::~Part_combine_music_iterator ()
+{
+ delete second_iter_p_;
+ delete first_iter_p_;
+}
+
+Moment
+Part_combine_music_iterator::next_moment () const
+{
+ Moment first_next = first_iter_p_->next_moment ();
+ Moment second_next = second_iter_p_->next_moment ();
+ return first_next <? second_next;
+}
+
+bool
+Part_combine_music_iterator::ok () const
+{
+ //hmm
+ return first_iter_p_->ok ();
+}
+
+void
+Part_combine_music_iterator::do_print () const
+{
+ first_iter_p_->print ();
+ second_iter_p_->print ();
+}
+
+void
+Part_combine_music_iterator::construct_children ()
+{
+ Part_combine_music const * m = dynamic_cast<Part_combine_music const*> (music_l_);
+
+ first_iter_p_ = get_iterator_p (m->first_l ());
+ second_iter_p_ = get_iterator_p (m->second_l ());
+}
+
+void
+Part_combine_music_iterator::change_to (Music_iterator *it, String to_type,
+ String to_id)
+{
+ Translator_group * current = it->report_to_l ();
+ Translator_group * last = 0;
+
+ /*
+ Cut & Paste from from Auto_change_iterator from Change_iterator (ugh).
+
+ TODO: abstract this function
+ */
+
+ /* find the type of translator that we're changing.
+
+ If \translator Staff = bass, then look for Staff = *
+ */
+ while (current && current->type_str_ != to_type)
+ {
+ last = current;
+ current = current->daddy_trans_l_;
+ }
+
+ if (current && current->id_str_ == to_id)
+ {
+ String msg;
+ msg += _ ("Can't switch translators, I'm there already");
+ }
+
+ if (current)
+ if (last)
+ {
+ Translator_group * dest =
+ it->report_to_l ()->find_create_translator_l (to_type, to_id);
+ current->remove_translator_p (last);
+ dest->add_translator (last);
+ }
+ else
+ {
+ /*
+ We could change the current translator's id, but that would make
+ errors hard to catch
+
+ last->translator_id_str_ = change_l ()->change_to_id_str_;
+ */
+ error (_f ("I'm one myself: `%s'", to_type.ch_C ()));
+ }
+ else
+ error (_f ("none of these in my family: `%s'", to_id.ch_C ()));
+}
+
+Pitch_interrogate_req* first_spanish_inquisition; // nobody expects it
+Pitch_interrogate_req* second_spanish_inquisition; // won't strike twice
+
+void
+Part_combine_music_iterator::do_process_and_next (Moment m)
+{
+ Moment first_next = first_iter_p_->next_moment ();
+ Moment second_next = second_iter_p_->next_moment ();
+
+ bool changed_b = false;
+ Part_combine_music const * p = dynamic_cast<Part_combine_music const* > (music_l_);
+
+ String to_id = combined_b_ ? "first" : "second";
+ /*
+ different rhythm for combined voices: separate
+ same rhythm for separated voices: combine
+ */
+ if ((first_next != second_next && combined_b_)
+ || (first_next == second_next && !combined_b_))
+ {
+ combined_b_ = !combined_b_;
+ to_id = combined_b_ ? "first" : "second";
+ change_to (second_iter_p_, p->what_str_, to_id);
+ changed_b = true;
+ }
+
+ Translator_group * fd =
+ first_iter_p_->report_to_l ()->find_create_translator_l (p->what_str_,
+ "first");
+ Translator_group * sd =
+ second_iter_p_->report_to_l ()->find_create_translator_l (p->what_str_,
+ to_id);
+
+ fd->set_property ("first", SCM_BOOL_T);
+ sd->set_property ("second", SCM_BOOL_T);
+
+ if (first_next <= m)
+ first_iter_p_->process_and_next (m);
+
+ if (second_next <= m)
+ second_iter_p_->process_and_next (m);
+
+ Music_iterator::do_process_and_next (m);
+
+ /*
+ TODO:
+
+ * "a2" string is fine, but "Soli" strings are one request late,
+ second a2 requests are junked one requst late...
+
+ The problem seems to be: we need to do_try_music for the
+ spanish_inquisition to work; but the properties that we set
+ need to be set *before* we do_try_music?
+
+ * setting of stem directions by a2-engraver don't work
+
+ * move much as possible code (changed?) to engravers: just notify
+ them of status: unison/solo. Engravers should be able to find
+ out whether something changed and if so, what to do.
+
+ * who should reset the properties, it's a mess now?
+
+
+ Later (because currently,we only handle thread swiching, really):
+
+ Maybe different modes exist?
+
+ * Wind instruments (Flute I/II)
+ * Hymnals:
+
+
+ Rules for Hymnals/SATB (John Henckel <henckel@iname.com>):
+
+ 1. if S and A differ by less than a third, the stems should be up/down.
+ 2. else if S and A have different values, the stems should be up/down.
+ 3. else if A sings "la" or higher, both S and A stems should be down.
+ 4. else both stems should be up
+
+ * This may get really tricky: combining voices/staffs: string instruments
+
+ */
+
+ if (!first_spanish_inquisition)
+ first_spanish_inquisition = new Pitch_interrogate_req;
+ Music_iterator* fit = first_iter_p_->try_music (first_spanish_inquisition);
+
+ if (!second_spanish_inquisition)
+ second_spanish_inquisition = new Pitch_interrogate_req;
+ Music_iterator* sit = second_iter_p_->try_music (second_spanish_inquisition);
+
+
+ // URG, moveme: just set properties
+ if (//changed_b
+ //&&
+ (first_next == second_next)
+ && first_spanish_inquisition->pitch_arr_.size ()
+ && (first_spanish_inquisition->pitch_arr_.size ()
+ == second_spanish_inquisition->pitch_arr_.size ())
+ && (first_spanish_inquisition->pitch_arr_[0] ==
+ second_spanish_inquisition->pitch_arr_[0]))
+ {
+ if (changed_b)
+ {
+ fd->set_property ("a2", SCM_BOOL_T);
+ sd->set_property ("a2", SCM_BOOL_T);
+ }
+ second_iter_p_->report_to_l ()->set_property ("a2", SCM_BOOL_T);
+ }
+ else
+ second_iter_p_->report_to_l ()->set_property ("a2", SCM_BOOL_F);
+
+ if (changed_b
+ && first_spanish_inquisition->pitch_arr_.size ()
+ && !second_spanish_inquisition->pitch_arr_.size ())
+ {
+ fd->set_property ("solo", SCM_BOOL_T);
+ }
+
+ if (changed_b
+ && !first_spanish_inquisition->pitch_arr_.size ()
+ && second_spanish_inquisition->pitch_arr_.size ())
+ {
+ sd->set_property ("solo2", SCM_BOOL_T);
+ }
+
+ first_spanish_inquisition->pitch_arr_.clear ();
+ second_spanish_inquisition->pitch_arr_.clear ();
+}
+
+Music_iterator*
+Part_combine_music_iterator::try_music_in_children (Music *m) const
+{
+ Music_iterator * i = first_iter_p_->try_music (m);
+ if (i)
+ return i;
+ else
+ return second_iter_p_->try_music (m);
+}
+
--- /dev/null
+/*
+ part-combine-music.cc -- implement Part_combine_music
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+
+#include "part-combine-music.hh"
+#include "musical-pitch.hh"
+
+Part_combine_music::Part_combine_music (String what, Music * f, Music * s)
+{
+ what_str_ = what;
+ set_mus_property ("first", f->self_scm ());
+ set_mus_property ("second", s->self_scm ());
+}
+
+
+void
+Part_combine_music::transpose (Musical_pitch p)
+{
+ first_l ()->transpose (p);
+ second_l () ->transpose (p);
+}
+
+void
+Part_combine_music::do_print () const
+{
+ first_l ()->print();
+ second_l () ->print ();
+}
+
+Moment
+Part_combine_music::length_mom () const
+{
+ return first_l ()->length_mom ();
+}
+
+Musical_pitch
+Part_combine_music::to_relative_octave (Musical_pitch p)
+{
+ p = first_l ()->to_relative_octave (p);
+ return second_l ()->to_relative_octave (p);
+}
+
+void
+Part_combine_music::compress (Moment m)
+{
+ first_l ()->compress (m);
+ second_l ()->compress (m);
+}
+
+Music*
+Part_combine_music::first_l () const
+{
+ return unsmob_music (get_mus_property ("first"));
+}
+
+Music*
+Part_combine_music::second_l () const
+{
+ return unsmob_music (get_mus_property ("second"));
+}
void
Property_engraver::apply_properties (SCM p, Score_element *e)
-{
+{
for (; gh_pair_p (p); p = gh_cdr (p))
{
/*
Score_element::Score_element(SCM basicprops)
{
+ /*
+ fixme: default should be no callback.
+ */
set_extent_callback (molecule_extent, X_AXIS);
set_extent_callback (molecule_extent, Y_AXIS);
Real r = (*c) (me,a );
if (isinf (r) || isnan (r))
{
- r = 0.0;
programming_error (INFINITY_MSG);
+ r = 0.0;
}
me->dim_cache_[a].offset_ +=r;
}
return cb == dim_cache_[a].extent_callback_l_;
}
+
+bool
+Score_element::has_extent_callback_b (Axis a) const
+{
+ return dim_cache_[a].extent_callback_l_;
+}
+
bool
Score_element::has_offset_callback_b (Offset_callback cb, Axis a)const
{
void
Span_bar::evaluate_empty (Score_element*me)
-{
+{
+ /*
+ TODO: filter all hara-kiried out of ELEMENS list, and then
+ optionally do suicide. Call this cleanage function from
+ center_on_spanned_callback() as well.
+
+ */
if (!gh_pair_p (me->get_elt_property ("elements")))
{
me->suicide ();
Interval iv (get_spanned_interval (me));
if (iv.empty_b ())
{
- programming_error("Huh? My children deflated (FIXME)");
- iv = Interval (0,0);
+ /*
+ This happens if the bars are hara-kiried from under us.
+ */
+ me->suicide ();
+ return gh_double2scm (-1);
}
return gh_double2scm (iv.length ());
}
text->set_elt_property ("style", ly_str02scm (r->style_str_.ch_C()));
/*
- huh?, this said:
-
- SCM empty = get_property ("textNonEmpty");
- if (to_boolean (empty))
- no-spacing-rods
-
Text is empty by default, which means that the only condition
for not setting 'no-spacing-rods' should be: boolean && true.
Anyway, non-empty text has been broken for some time now.
*/
SCM nonempty = get_property ("textNonEmpty");
- if (to_boolean (nonempty))
- ;
- else
- {
- text->set_elt_property ("no-spacing-rods" , SCM_BOOL_F);
- text->set_extent_callback (0, X_AXIS);
- }
+ if (!to_boolean (nonempty))
+ /*
+ empty text: signal that no rods should be applied.
+ */
+ text->set_elt_property ("no-spacing-rods" , SCM_BOOL_T);
+
+
announce_element (text, r);
texts_.push (text);
}
\consists "Melisma_engraver";
textScriptPadding = #3.0
\consists "Text_engraver";
+ \consists "A2_engraver";
startSustain = #"Ped."
ThreadContext = \translator{
\type Engraver_group_engraver;
- \consists "Note_heads_engraver" ;
+ \consists "A2_devnull_engraver";
+ \consists "Note_heads_engraver";
\consists "Output_property_engraver";
Generic_property_list = #generic-thread-properties
\consists "Property_engraver";
basicChordNameProperties = #`(
(molecule-callback . ,Chord_name::brew_molecule)
(interfaces . (chord-name-interface))
+ (after-line-breaking-callback . ,Chord_name::after_line_breaking)
)
basicCollisionProperties = #`(
(axes 0 1)
(interfaces . (dot-interface))
)
basicDynamicLineSpannerProperties = #`(
- (interfaces (dynamic-interface axis-group-interface))
+ (interfaces . (dynamic-interface axis-group-interface))
(axes . ( 1))
)
basicDynamicTextProperties = # `(
(style . "dynamic")
- (interface (dynamic-interface))
+ (interfaces . (dynamic-interface))
(molecule-callback . ,Text_item::brew_molecule)
(script-priority . 100)
(self-alignment-Y . 0)
)
basicTextScriptProperties = #`(
(molecule-callback . ,Text_item::brew_molecule)
- (no-spacing-rods . #t)
+
+: -- don't set, because property-engraver will not override it.
+; (no-spacing-rods . #t)
(interfaces . (text-script-interface text-item-interface))
)
basicTieProperties = #`(