function. Keep ledgered note heads at a minimum distance.
Introduce minimum-length-fraction
(print): introduce length-fraction property.
+2005-03-09 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * lily/ledger-line-spanner.cc (set_spacing_rods): new
+ function. Keep ledgered note heads at a minimum distance.
+ Introduce minimum-length-fraction
+ (print): introduce length-fraction property.
+
+2005-03-08 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * tex/GNUmakefile: remove latin1.enc rules.
+
2005-03-08 Jan Nieuwenhuizen <janneke@gnu.org>
* scm/titling.scm: Typo.
struct Rod
{
- Drul_array <Item*> item_l_drul_;
+ Drul_array <Item*> item_drul_;
Real distance_;
/**
struct Spring
{
- Drul_array<Item*> item_l_drul_;
+ Drul_array<Item*> item_drul_;
Real distance_;
bool expand_only_b_;
*/
#include <map>
+#include <set>
+#include "item.hh"
#include "note-head.hh"
#include "staff-symbol-referencer.hh"
#include "staff-symbol.hh"
struct Ledger_line_spanner
{
DECLARE_SCHEME_CALLBACK (print, (SCM ));
+ DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM ));
static Stencil brew_ledger_lines (Grob *me,
int pos,
int interspaces,
}
+typedef std::map<int, Drul_array<Interval> > Head_extents_map;
+typedef std::map<int, Grob*> Column_map;
+
+MAKE_SCHEME_CALLBACK (Ledger_line_spanner, set_spacing_rods, 1);
+SCM
+Ledger_line_spanner::set_spacing_rods (SCM smob)
+{
+ Spanner *me = dynamic_cast<Spanner*> (unsmob_grob (smob));
+
+ // find size of note heads.
+ Grob * staff = Staff_symbol_referencer::get_staff_symbol (me);
+ if (!staff)
+ return SCM_EOL;
+
+ Link_array<Grob> heads (Pointer_group_interface__extract_grobs (me, (Grob*)0, "note-heads"));
+
+ if (heads.is_empty ())
+ return SCM_EOL;
+
+ Real min_length_fraction
+ = robust_scm2double (me->get_property ("minimum-length-fraction"), 0.15);
+
+ Head_extents_map head_extents;
+ Column_map columns;
+
+ int interspaces = Staff_symbol::line_count (staff)-1;
+ for (int i = heads.size (); i--; )
+ {
+ Item *h = dynamic_cast<Item*> (heads[i]);
+
+ int pos = Staff_symbol_referencer::get_rounded_position (h);
+ if (pos
+ && abs (pos) > interspaces)
+ {
+ Grob *column = h->get_column ();
+ int rank = Paper_column::get_rank (column);
+
+ Interval head_extent = h->extent (column, X_AXIS);
+ Direction vdir = Direction (sign (pos));
+ if (!vdir)
+ continue;
+
+ Interval prev_extent;
+
+ Head_extents_map::iterator j = head_extents.find (rank);
+ if (j != head_extents.end ())
+ prev_extent = (*j).second[vdir];
+ else
+ columns[rank] = column;
+
+ prev_extent.unite (head_extent);
+ head_extents[rank][vdir] = prev_extent;
+ }
+ }
+
+ for (Column_map::const_iterator c (columns.begin()); c != columns.end(); c++)
+ {
+ Grob *column = (*c).second;
+ int rank = (*c).first;
+
+ int next_rank = rank + 2;
+
+ if (head_extents.find (next_rank) != head_extents.end ())
+ {
+ Drul_array<Interval> extents_left = head_extents[rank];
+ Drul_array<Interval> extents_right = head_extents[next_rank];
+
+ Direction d = DOWN;
+ do
+ {
+ if (!extents_right[d].is_empty () && !extents_right[d].is_empty ())
+ {
+ Real l1 = extents_right[d].length() * min_length_fraction;
+ Real l2 = extents_left[d].length() * min_length_fraction;
+
+ Rod rod;
+ rod.distance_ = l1 + l2 + (l1+ l2)/2.0
+ + extents_left[d][RIGHT]
+ - extents_right[d][LEFT];
+
+ rod.item_drul_[LEFT] = dynamic_cast<Item*> (column);
+ rod.item_drul_[RIGHT] = dynamic_cast<Item*> (columns[next_rank]);
+ rod.add_to_cols ();
+ }
+ }
+ while (flip (&d) != DOWN);
+ }
+ }
+
+ return SCM_UNSPECIFIED;
+}
+
+
struct Ledger_request
{
Interval ledger_extent_;
return SCM_EOL;
+ Real length_fraction
+ = robust_scm2double (me->get_property ("length-fraction"), 0.25);
+
Stencil ledgers;
Stencil default_ledger;
int interspaces = Staff_symbol::line_count (staff)-1;
Ledger_requests reqs;
- Real length_fraction = 0.25;
for (int i = heads.size (); i--; )
{
Item *h = dynamic_cast<Item*> (heads[i]);
}
}
-
ledgers.translate_axis (-me->relative_coordinate (common[X_AXIS], X_AXIS),
X_AXIS);
ADD_INTERFACE (Ledger_line_spanner,
"ledger-line-interface",
"This spanner draws the ledger lines of a staff, for note heads that stick out. ",
- "note-heads thickness gap length minimum-length");
+ "note-heads thickness minimum-length-fraction length-fraction gap");
struct Ledgered_interface {
Direction d = LEFT;
do
{
- r.item_l_drul_[d] = sp->get_bound (d);
- if (r.item_l_drul_[d])
- r.distance_ += r.item_l_drul_[d]->extent (r.item_l_drul_[d], X_AXIS)[-d];
+ r.item_drul_[d] = sp->get_bound (d);
+ if (r.item_drul_[d])
+ r.distance_ += r.item_drul_[d]->extent (r.item_drul_[d], X_AXIS)[-d];
}
while (flip (&d) != LEFT);
- if (r.item_l_drul_[LEFT]
- && r.item_l_drul_[RIGHT])
+ if (r.item_drul_[LEFT]
+ && r.item_drul_[RIGHT])
r.add_to_cols ();
return SCM_UNSPECIFIED;
continue;
Rod rod;
- rod.item_l_drul_[LEFT] = li;
- rod.item_l_drul_[RIGHT] = ri;
+ rod.item_drul_[LEFT] = li;
+ rod.item_drul_[RIGHT] = ri;
rod.distance_ = li->extent (li, X_AXIS)[BIGGER]
- ri->extent (ri, X_AXIS)[SMALLER]
{
char const *name_;
Music* start_req_;
- Drul_array<Music*> req_l_drul_;
+ Drul_array<Music*> req_drul_;
};
public:
do
{
p->name_ = *np;
- p->req_l_drul_[START] = 0;
- p->req_l_drul_[STOP] = 0;
+ p->req_drul_[START] = 0;
+ p->req_drul_[STOP] = 0;
p->start_req_ = 0;
p++;
for (Pedal_info*p = info_alist_; p && p->name_; p ++)
{
- if (p->req_l_drul_[STOP])
+ if (p->req_drul_[STOP])
{
if (!p->start_req_)
{
- p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", String (p->name_)));
+ p->req_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", String (p->name_)));
}
else
{
p->start_req_ = 0;
}
- if (p->req_l_drul_[START])
+ if (p->req_drul_[START])
{
- p->start_req_ = p->req_l_drul_[START];
+ p->start_req_ = p->req_drul_[START];
Audio_piano_pedal* a = new Audio_piano_pedal;
a->type_string_ = String (p->name_);
a->dir_ = START;
audios_.push (a);
}
- p->req_l_drul_[START] = 0;
- p->req_l_drul_[STOP] = 0;
+ p->req_drul_[START] = 0;
+ p->req_drul_[STOP] = 0;
}
}
{
for (Pedal_info*p = info_alist_; p && p->name_; p ++)
{
- p->req_l_drul_[STOP] = 0;
- p->req_l_drul_[START] = 0;
+ p->req_drul_[STOP] = 0;
+ p->req_drul_[START] = 0;
}
}
scm_str2symbol (nm.to_str0())))
{
Direction d = to_dir (r->get_property ("span-direction"));
- p->req_l_drul_[d] = r;
+ p->req_drul_[d] = r;
return true;
}
}
Rod::Rod ()
{
distance_ = 0.0;
- item_l_drul_[LEFT] = item_l_drul_[RIGHT] = 0;
+ item_drul_[LEFT] = item_drul_[RIGHT] = 0;
}
void
Rod::columnize ()
{
- if (!item_l_drul_[LEFT]
- || !item_l_drul_[RIGHT])
+ if (!item_drul_[LEFT]
+ || !item_drul_[RIGHT])
return ;
Direction d = LEFT;
do {
- Paper_column * pc = item_l_drul_[d]->get_column ();
- distance_ += - d * item_l_drul_[d]->relative_coordinate (pc, X_AXIS);
- item_l_drul_[d] = pc;
+ Paper_column * pc = item_drul_[d]->get_column ();
+ distance_ += - d * item_drul_[d]->relative_coordinate (pc, X_AXIS);
+ item_drul_[d] = pc;
} while ((flip (&d))!= LEFT);
}
Rod::add_to_cols ()
{
columnize ();
- if (item_l_drul_[LEFT] != item_l_drul_[RIGHT]
- && item_l_drul_[LEFT] && item_l_drul_[RIGHT])
- Spaceable_grob::add_rod (item_l_drul_[LEFT],
- item_l_drul_[RIGHT],
+ if (item_drul_[LEFT] != item_drul_[RIGHT]
+ && item_drul_[LEFT] && item_drul_[RIGHT])
+ Spaceable_grob::add_rod (item_drul_[LEFT],
+ item_drul_[RIGHT],
distance_);
}
{
Rod rod;
- rod.item_l_drul_[LEFT] = lb;
- rod.item_l_drul_[RIGHT] = r;
+ rod.item_drul_[LEFT] = lb;
+ rod.item_drul_[RIGHT] = r;
rod.distance_ = li[RIGHT] - ri[LEFT] + padding;
rod.add_to_cols ();
{
Rod rod;
- rod.item_l_drul_[LEFT] = l;
- rod.item_l_drul_[RIGHT]= r;
+ rod.item_drul_[LEFT] = l;
+ rod.item_drul_[RIGHT]= r;
rod.distance_ = li[RIGHT] - ri[LEFT] + padding;
ADD_INTERFACE (Separation_item, "separation-item-interface",
"Item that computes widths to generate spacing rods. "
"This is done in concert with @ref{separation-spanner-interface}."
-
,
-
"padding X-extent conditional-elements elements");
Rod r;
r.distance_ = dists[LEFT] + dists[RIGHT];
- r.item_l_drul_[LEFT] = dynamic_cast<Item*> (cols->elem (i-1));
- r.item_l_drul_[RIGHT] = dynamic_cast<Item*> (cols->elem (i+1));
+ r.item_drul_[LEFT] = dynamic_cast<Item*> (cols->elem (i-1));
+ r.item_drul_[RIGHT] = dynamic_cast<Item*> (cols->elem (i+1));
r.add_to_cols ();
}
Rod r;
Spanner*sp = dynamic_cast<Spanner*> (me);
- r.item_l_drul_[LEFT] = sp->get_bound (LEFT);
- r.item_l_drul_[RIGHT] = sp->get_bound (RIGHT);
+ r.item_drul_[LEFT] = sp->get_bound (LEFT);
+ r.item_drul_[RIGHT] = sp->get_bound (RIGHT);
r.distance_ =
robust_scm2double (me->get_property ("minimum-length"), 0);
(else 'latin1)))
;; add to taste here.
- (baseline-skip . 2)
+ (baseline-skip . 3)
(word-space . 0.6)))
#(define page-breaking ly:optimal-page-breaks)
(newline (current-error-port))
;; hmmm. what's the best failure option?
- (throw 'ly-file-failed))))
+ (throw 'ly-file-failed)))))
(define-public (sanitize-command-option str)
(string-append
left to a group of accidentals.")
(length ,ly:dimension? "User override for the stem length of
unbeamed stems.")
+ (length-fraction ,number? "Length of ledger line as fraction of note head size.")
(lengths ,list? "Default stem lengths. The list gives a length
for each flag-count.")
(line-count ,integer? "The number of staff lines.")
collisions, even if they have a different number of dots. This normal
notation for some types of polyphonic music. ")
+ (minimum-length-fraction ,number? "Minimum length of ledger line as fraction of note head size.")
(minimum-distance ,ly:dimension? "Minimum distance between rest
and notes or beam.")
(minimum-X-extent ,number-pair? "Minimum size of an object in X
(print-function . ,Ledger_line_spanner::print)
(X-extent-callback . #f)
(Y-extent-callback . #f)
+ (spacing-procedure . ,Ledger_line_spanner::set_spacing_rods)
(print-function . ,Ledger_line_spanner::print)
(layer . 0)
(meta . ((interfaces . (spanner-interface ledger-line-interface))))