2002-07-23 Han-Wen <hanwen@cs.uu.nl>
+ * lily/accidental-placement.cc (split_accidentals): new function
+ (get_relevant_accidental_extent): new function
+
+ * lily/staff-spacing.cc (next_note_correction): idem
+
+ * lily/separating-group-spanner.cc (find_rods): use conditional_width().
+
* scm/sketch.scm: fix roundfilledbox definition
* lily/lily-guile.cc (robust_list_ref): be sensible with negative
-LilyPond development is hosted at savannah.gnu.org/projects/lilypond
+LilyPond development is hosted at http://savannah.gnu.org/projects/lilypond
Here is an attempt at a simple explanation of the directory layout for
LilyPond's source files.
#include "note-collision.hh"
#include "accidental-interface.hh"
+/*
+ Hmm. why not group-extent?
+ */
MAKE_SCHEME_CALLBACK(Accidental_placement,extent_callback, 2);
SCM
Accidental_placement::extent_callback(SCM s, SCM axis)
me->set_grob_property ("accidentals", accs);
}
+/*
+ Split into break reminders.
+ */
+void
+Accidental_placement::split_accidentals (Grob * accs,
+ Link_array<Grob> *break_reminder,
+ Link_array<Grob> *real_acc)
+{
+ for (SCM acs =accs->get_grob_property ("accidentals"); gh_pair_p (acs);
+ acs =gh_cdr (acs))
+ for (SCM s = gh_cdar (acs); gh_pair_p (s); s = gh_cdr (s))
+ {
+ Grob *a = unsmob_grob (gh_car (s));
+
+ if (unsmob_grob (a->get_grob_property ("tie")))
+ break_reminder->push (a);
+ else
+ real_acc->push (a);
+ }
+}
+
+/*
+ Accidentals are special, because they appear and disappear before
+ and after ties at will.
+*/
+Interval
+Accidental_placement::get_relevant_accidental_extent (Grob *me,
+ Item *item_col,
+ Grob *left_object)
+{
+ Link_array<Grob> br, ra;
+ Link_array<Grob> *which = 0;
+
+ Accidental_placement::split_accidentals (me, &br, &ra);
+ br.concat (ra);
+
+ if (dynamic_cast<Item*>(left_object)->break_status_dir () == RIGHT)
+ which = & br;
+ else
+ which = & ra;
+
+ Interval extent;
+ for (int i = 0; i < which->size(); i++)
+ {
+ extent.unite (which->elem(i)->extent (item_col, X_AXIS));
+ }
+
+ if (!extent.empty_b())
+ {
+ Real p = gh_scm2double (me->get_grob_property ("left-padding"));
+ extent[LEFT] -= p;
+ }
+
+ return extent;
+}
+
+
+
struct Accidental_placement_entry
{
Array<Skyline_entry> left_skyline_;
DECLARE_SCHEME_CALLBACK (extent_callback, (SCM element, SCM axis));
static void add_accidental (Grob *,Grob* );
+ static Interval get_relevant_accidental_extent (Grob *me,
+ Item *item_col,
+ Grob *acc);
+ static void split_accidentals (Grob * accs,
+ Link_array<Grob> *break_reminder,
+ Link_array<Grob> *real_acc);
static SCM position_accidentals (Grob* );
static bool has_interface (Grob*);
struct Separation_item
{
static bool has_interface (Grob*);
- static Interval my_width (Grob*) ;
+ static Interval conditional_width (Grob*,Grob*) ;
+ static Interval width (Grob*) ;
+
static void add_item (Grob*,Item*);
+ static void add_conditional_item (Grob*,Grob*);
};
#endif /* SINGLE_MALT_GROUPING_ITEM_HH */
#include "stem.hh"
#include "separation-item.hh"
#include "staff-spacing.hh"
-
+#include "accidental-placement.hh"
void
Note_spacing::get_spacing (Grob *me, Item* right_col,
if (Separation_item::has_interface (it))
{
- extents[d].unite (Separation_item::my_width (it));
+ extents[d].unite (Separation_item::width (it));
continue;
}
accs = Note_column::accidentals (it->get_parent (X_AXIS));
if (accs)
- extents[d].unite (accs->extent (it_col, X_AXIS));
+ {
+ Interval v =
+ Accidental_placement::get_relevant_accidental_extent (accs, it_col, me);
+
+ extents[d].unite (v);
+ }
}
}
void
Separating_group_spanner::find_rods (Item * r, SCM next)
{
- Interval ri (Separation_item::my_width (r));
- if (ri.empty_b ())
- return;
/*
This is an inner loop, however, in most cases, the interesting L
if (lb)
{
- Interval li (Separation_item::my_width (lb));
-
- if (!li.empty_b ())
+ Interval li (Separation_item::width (lb));
+ Interval ri (Separation_item::conditional_width (r, lb));
+ if (!li.empty_b () && !ri.empty_b())
{
Rod rod;
}
}
- Interval li (Separation_item::my_width (l));
- if (!li.empty_b ())
+ Interval li (Separation_item::width (l));
+ Interval ri (Separation_item::conditional_width (r, l));
+ if (!li.empty_b () && !ri.empty_b())
{
Rod rod;
#include "axis-group-interface.hh"
#include "note-spacing.hh"
#include "group-interface.hh"
+#include "accidental-placement.hh"
struct Spacings
{
->has_extent_callback_b(Axis_group_interface::group_extent_callback_proc, X_AXIS))
return;
-
if (to_boolean (it->get_grob_property ("no-spacing-rods")))
return ;
}
}
- Separation_item::add_item (p_ref_,it);
+ if (Accidental_placement::has_interface (it))
+ Separation_item::add_conditional_item (p_ref_, it);
+ else
+ Separation_item::add_item (p_ref_,it);
}
void
#include "paper-column.hh"
#include "warn.hh"
#include "group-interface.hh"
-
+#include "accidental-placement.hh"
void
Separation_item::add_item (Grob*s,Item* i)
s->add_dependency (i);
}
-/*
- DOCME:
+void
+Separation_item::add_conditional_item (Grob* me , Grob *e)
+{
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("conditional-elements"), e);
+}
- why don't we use extent()
- */
Interval
-Separation_item::my_width (Grob *me)
+Separation_item::conditional_width (Grob * me, Grob * left)
{
+ Interval w = width (me);
+
+ Item *item = dynamic_cast<Item*> (me);
+ Paper_column * pc = item->column_l ();
+
+
+ for (SCM s = me->get_grob_property ("conditional-elements"); gh_pair_p (s); s = ly_cdr (s))
+ {
+ SCM elt = ly_car (s);
+ if (!unsmob_grob (elt))
+ continue;
+
+ Item *il = unsmob_item (elt);
+ if (pc != il->column_l ())
+ {
+ /* this shouldn't happen, but let's continue anyway. */
+ programming_error (_ ("Separation_item: I've been drinking too much"));
+ continue; /*UGH UGH*/
+ }
+
+ if (to_boolean (il->get_grob_property ("no-spacing-rods")))
+ {
+ continue;
+ }
+
+ if (Accidental_placement::has_interface (il))
+ {
+ w.unite (Accidental_placement::get_relevant_accidental_extent (il, pc, left));
+ }
+ }
+
+ SCM pad = me->get_grob_property ("padding");
+
+ if (gh_number_p (pad))
+ {
+ w[RIGHT] += gh_scm2double (pad)/2;
+ w[LEFT] -= gh_scm2double (pad)/2;
+ }
+ return w;
+}
+
+Interval
+Separation_item::width (Grob *me)
+{
+ SCM sw = me->get_grob_property ("extent-X");
+ if (ly_number_pair_p (sw))
+ {
+ return ly_scm2interval (sw);
+ }
+
Item *item = dynamic_cast<Item*> (me);
Paper_column * pc = item->column_l ();
Interval w;
w[RIGHT] += gh_scm2double (pad)/2;
w[LEFT] -= gh_scm2double (pad)/2;
}
+
+
+ me->set_grob_property ("extent-X", ly_interval2scm (w));
+
return w;
// add this->offset_ ? this-> relative_coordinate ()?
an item to get dependencies correct. It can't be an grob_group
since these usually are in a different X_group
",
- "elements");
+ "extent-X conditional-elements elements");
#include "staff-symbol-referencer.hh"
#include "note-column.hh"
#include "stem.hh"
+#include "accidental-placement.hh"
/*
Insert some more space for the next note, in case it has a stem in
*/
if (Grob * a = Note_column::accidentals (g))
{
- max_corr = max_corr >? (- a->extent (col, X_AXIS)[LEFT]);
+ Interval v= Accidental_placement::get_relevant_accidental_extent
+ (a, col, me);
+
+ max_corr = max_corr >? (- v[LEFT]);
}
if (Grob* a = unsmob_grob (g->get_grob_property ("arpeggio")))
{
))
(AccidentalPlacement
. (
- (X-extent-callback . ,Accidental_placement::extent_callback)
+ (X-extent-callback . ,Axis_group_interface::group_extent_callback)
(left-padding . 0.3)
(right-padding . 0.3)
(meta . ((interfaces . (item-interface accidental-placement-interface))))
(grob-property-description 'collapse-height number? "Minimum height of system start delimiter. If equal or smaller, the bracket is removed.")
(grob-property-description 'columns grob-list? "list of grobs, typically containing paper-columns.")
+(grob-property-description 'conditional-elements grob-list? "Internal use only")
(grob-property-description 'control-points list? "List of 4 offsets (number-pairs) that form control points for the tie/slur shape.")
(grob-property-description 'damping integer? "amount of beam slope damping should beam slope be damped? 0: no, 1: yes, 100000: horizontal beams .")
(grob-property-description 'dash-length number? "the length of a dash.")
(grob-property-description 'expand-limit integer? "maximum number of measures expanded in church rests.")
(grob-property-description 'extra-extent-X number-pair? "enlarge in X dimension by this much, measured in staff space.")
(grob-property-description 'extra-extent-Y number-pair? "see @code{extra-extent-Y}.")
+(grob-property-description 'extent-X number-pair? "Store extent. internal use only. ")
(grob-property-description 'extra-offset number-pair? "pair of reals
(a cons) forcing an extra offset before outputting.
@code{extra-offset} is added just before `printing' the grob, so the
All visible, i.e. non-transparent, grobs have a callback to create a
Molecule. The callback should be a Scheme function taking one argument
(the grob) and returning a Molecule. Most molecule callbacks are
-written in C++, but you can also write them in Scheme. An example is
+written in C++, but you can also write them in Scheme. An examlily/lilypond/ple is
provided in @code{input/regression/molecule-hacking.ly}.
")