static T infinity ();
static String T_to_string (T arg);
- T center () const
- {
- assert (!is_empty ());
- return (elem (LEFT) + elem (RIGHT)) / T (2);
- }
+ T center () const;
void translate (T t)
{
elem_ref (LEFT) += t;
return a*i;
}
+
+template<class T>
+inline T
+Interval_t<T>::center () const
+{
+ assert (!is_empty ());
+ return (elem (LEFT) + elem (RIGHT)) / T (2);
+}
+
// again? see flower-proto.hh
typedef Interval_t<Real> Interval;
typedef Interval_t<int> Slice; // weird name
return -2;
}
+
template<class T>
bool
Interval_t<T>::superset (Interval_t<T> const& a) const
--- /dev/null
+\header {
+ texidoc = "Ledger lines are shortened when they are very close. This ensures
+that ledgers lines stay separate."
+}
+\version "2.3.7"
+
+\paper {
+ raggedright = ##t
+}
+
+\relative {
+\time 2/4
+
+c4
+b
+c4
+b
+a g
+c32[ b c d]
+b[ c d c]
+b[ d d b]
+b[ e e b]
+c[ d d c]
+c[ e e c]
+
+
+
+}
#include "staff-symbol-referencer.hh"
#include "event.hh"
#include "pitch.hh"
+#include "pitch-interval.hh"
+#include "protected-scm.hh"
-/*
- UGH UGH UGH .
-
- rewrite this complely. --hwn
- */
/*
* This class implements an engraver for ambitus grobs.
private:
void create_ambitus ();
Item *ambitus_;
- bool is_typeset;
- Pitch pitch_min, pitch_max;
+ Drul_array<Item *> heads_;
+ Drul_array<Item *> accidentals_;
+ Pitch_interval pitch_interval_;
+ bool is_typeset_;
+ int start_c0_;
+ Protected_scm start_key_sig_;
};
+void
+Ambitus_engraver::create_ambitus ()
+{
+ ambitus_ = make_item ("Ambitus",SCM_EOL);
+ is_typeset_ = false;
+}
+
+
Ambitus_engraver::Ambitus_engraver ()
{
ambitus_ = 0;
- is_typeset = 0;
-
- /*
- * (pitch_min > pitch_max) means that pitches are not yet
- * initialized
- */
- pitch_min = Pitch (0, 0, SHARP);
- pitch_max = Pitch (0, 0, FLAT);
+ is_typeset_ = false;
}
void
* Otherwise, if a voice begins with a rest, the ambitus grob will
* be placed after the rest.
*/
- if (!ambitus_) {
- create_ambitus ();
- }
+ if (!ambitus_)
+ {
+ create_ambitus ();
+ }
}
void
Ambitus_engraver::stop_translation_timestep ()
{
- if (ambitus_ && !is_typeset)
+ if (ambitus_ && !is_typeset_)
{
/*
* Evaluate middleCPosition not until now, since otherwise we
* we are in a voice context; middleCPosition would then be
* assumed to be 0.
*/
- SCM c0 = get_property ("middleCPosition");
- ambitus_->set_property ("c0-position", c0);
-
- /*
- * Similar for keySignature.
- */
- SCM key_signature = get_property ("keySignature");
- ambitus_->set_property ("accidentals", key_signature);
+ start_c0_ = robust_scm2int (get_property ("middleCPosition"), 0);
+ start_key_sig_ = get_property ("keySignature");
-
- is_typeset = true;
+ Direction d = DOWN;
+ do
+ {
+ heads_[d] = make_item ("AmbitusNoteHead", SCM_EOL);
+ accidentals_[d] = make_item ("AmbitusAccidental", SCM_EOL);
+ heads_[d]->set_property ("accidental-grob", accidentals_[d]->self_scm ());
+ }
+ while (flip (&d) != DOWN);
+ is_typeset_ = true;
}
}
if (nr && nr->is_mus_type ("note-event"))
{
Pitch pitch = *unsmob_pitch (nr->get_property ("pitch"));
- if (Pitch::compare (pitch_min, pitch_max) > 0) // already init'd?
- {
- // not yet init'd; use current pitch to init min/max
- pitch_min = pitch;
- pitch_max = pitch;
- }
- else if (Pitch::compare (pitch, pitch_max) > 0) // new max?
- {
- pitch_max = pitch;
- }
- else if (Pitch::compare (pitch, pitch_min) < 0) // new min?
- {
- pitch_min = pitch;
- }
+ pitch_interval_.add_point (pitch);
}
}
}
}
-void
-Ambitus_engraver::create_ambitus ()
-{
- ambitus_ = make_item ("Ambitus",SCM_EOL);
- is_typeset = false;
-}
-
void
Ambitus_engraver::finalize ()
{
- if (ambitus_)
+ if (ambitus_ && !pitch_interval_.is_empty ())
{
- if (Pitch::compare (pitch_min, pitch_max) <= 0)
- {
- ambitus_->set_property ("pitch-min",
- pitch_min.smobbed_copy ());
- ambitus_->set_property ("pitch-max",
- pitch_max.smobbed_copy ());
- }
- else // have not seen any pitch, so forget about the ambitus
+ Direction d = DOWN;
+ do
{
- /*
- * Do not print a warning on empty ambitus range, since this
- * most probably arises from an empty voice, such as shared
- * global timesig/clef definitions.
- */
- ambitus_->suicide ();
+ Pitch p = pitch_interval_[d];
+ heads_[d]->set_property ("position",
+ scm_from_int (start_c0_ +
+ p.steps ()));
+
+ SCM handle = scm_assoc (scm_cons (scm_from_int (p.get_octave ()),
+ scm_from_int (p.get_notename ())),
+ start_key_sig_);
+
+ int sig_alter = (handle != SCM_BOOL_F) ? ly_scm2int (ly_car (handle)) : 0;
+ if (sig_alter == p.get_alteration ())
+ {
+ accidentals_[d]->suicide();
+ heads_[d]->set_property ("accidental-grob", SCM_EOL);
+ }
+ else
+ {
+ accidentals_[d]->set_property ("accidentals",
+ scm_list_1 (scm_from_int (p.get_alteration ())));
+ }
}
+ while (flip (&d) != DOWN);
+
+ ambitus_->set_property ("note-heads", scm_list_2 (heads_[DOWN]->self_scm (),
+ heads_[UP]->self_scm ()));
+ }
+ else
+ {
+ Direction d = DOWN;
+ do
+ {
+ accidentals_[d]->suicide();
+ heads_[d]->suicide();
+ }
+ while (flip (&d) != DOWN);
+ ambitus_->suicide();
}
}
return 2;
}
+
+
void
add_accidentals (Item *me, Stencil *head, int num_acc,
Pitch *pitch, String accidentals_style, Real yoffs)
FIXME: Use positions.
*/
int p_min, p_max;
- Pitch *pitch_min = unsmob_pitch (me->get_property ("pitch-min"));
- if (!pitch_min)
- {
- me->programming_error ("Ambitus: pitch_min undefined; assuming 0");
- p_min = 0;
- }
- else
- {
- p_min = pitch_min->steps ();
- }
- Pitch *pitch_max = unsmob_pitch (me->get_property ("pitch-max"));
- if (!pitch_max)
- {
- me->programming_error ("Ambitus: pitch_max undefined; assuming 0");
- p_max = 0;
- }
- else
- {
- p_max = pitch_max->steps ();
- }
- if (p_min > p_max)
- {
- me->programming_error ("Ambitus: reverse range");
- }
-
- SCM c0 = me->get_property ("c0-position");
- if (ly_c_number_p (c0))
- {
- p_min += ly_scm2int (c0);
- p_max += ly_scm2int (c0);
- }
+ Slice posns = get_positions(me);
+
+ p_min = posns[LEFT];
+ p_max = posns[RIGHT];
// create heads
Stencil head_min =
stencil.add_stencil (line);
}
- // add ledger lines
- Interval hd = head_min.extent (X_AXIS);
- Real left_ledger_protusion = hd.length () / 4;
- Real right_ledger_protusion = left_ledger_protusion;
- Interval l_extents = Interval (hd[LEFT] - left_ledger_protusion,
- hd[RIGHT] + right_ledger_protusion);
- Stencil ledger_lines;
- int interspaces = Staff_symbol_referencer::line_count (me) - 1;
- ledger_lines =
- Note_head::brew_ledger_lines (me, p_min, interspaces, l_extents, 0,true);
- ledger_lines.translate_axis (0.5 * p_min, Y_AXIS);
- stencil.add_stencil (ledger_lines);
- ledger_lines =
- Note_head::brew_ledger_lines (me, p_max, interspaces, l_extents, 0, true);
- ledger_lines.translate_axis (0.5 * p_max, Y_AXIS);
- stencil.add_stencil (ledger_lines);
-
+
// add accidentals
SCM key_signature = me->get_property ("key-signature");
SCM scm_accidentals_style = me->get_property ("accidentals-style");
}
int num_acc;
+ Pitch *pitch_min = unsmob_pitch (me->get_property ("pitch-min"));
+ Pitch *pitch_max = unsmob_pitch (me->get_property ("pitch-max"));
num_acc = number_accidentals (key_signature, pitch_min, true, false);
add_accidentals (me, &head_min, num_acc, pitch_min,
accidentals_style, 0.5 * p_min);
me->warning (_f ("custos `%s' not found", font_char));
return SCM_EOL;
}
- else
- {
- // add ledger lines
- int pos = Staff_symbol_referencer::get_rounded_position (me);
- int interspaces = Staff_symbol_referencer::line_count (me)-1;
- if (abs (pos) - interspaces > 1)
- {
- Stencil ledger_lines =
- Note_head::brew_ledger_lines (me, pos, interspaces,
- stencil.extent (X_AXIS), 0, true);
- stencil.add_stencil (ledger_lines);
- }
- return stencil.smobbed_copy ();
- }
+
+ return stencil.smobbed_copy ();
}
ADD_INTERFACE (Custos, "custos-interface",
{
DECLARE_SCHEME_CALLBACK (print, (SCM smob));
static bool has_interface (Grob*);
+ static Slice get_positions (Grob*);
+ static Interval head_width (Grob* me, Grob * common);
};
#endif // AMBITUS_HH
public:
DECLARE_SCHEME_CALLBACK (print, (SCM ));
static Interval head_extent (Grob*, Axis);
- static Stencil brew_ledger_lines (Grob *me, int pos, int interspaces,
- Interval x_extent, Real, bool);
DECLARE_SCHEME_CALLBACK (brew_ez_stencil, (SCM));
DECLARE_SCHEME_CALLBACK (extent, (SCM,SCM));
static bool has_interface (Grob*);
--- /dev/null
+/*
+ pitch-interval.hh -- declare Pitch_interval
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#ifndef PITCH_INTERVAL_HH
+#define PITCH_INTERVAL_HH
+
+#include "pitch.hh"
+#include "drul-array.hh"
+
+class Pitch_interval : public Drul_array<Pitch>
+{
+public:
+ Pitch_interval();
+ Pitch_interval(Pitch, Pitch);
+ void add_point (Pitch);
+ bool is_empty () const;
+};
+
+#endif /* PITCH_INTERVAL_HH */
#include "group-interface.hh"
#include "spanner.hh"
#include "engraver.hh"
+#include "ambitus.hh"
class Ledger_line_engraver : public Engraver
{
Pointer_group_interface::add_grob (span_, ly_symbol2scm ("note-heads"),
s.grob_);
}
-
ENTER_DESCRIPTION (Ledger_line_engraver,
"Creates spanner to draw ledger lines",
/* creats*/ "LedgerLineSpanner",
/* accepts */ "",
- /* acks */ "note-head-interface", // ledgered-interface?
+ /* acks */ "custos-interface note-head-interface", // ledgered-interface?
/* reads */ "",
/* write */ "")
#include "spanner.hh"
#include "group-interface.hh"
#include "paper-column.hh"
+#include "ambitus.hh"
struct Ledger_line_spanner
{
DECLARE_SCHEME_CALLBACK (print, (SCM ));
static Stencil brew_ledger_lines (Grob *me,
- int pos,
- int interspaces,
- Interval x_extent,
- Real left_shorten);
+ int pos,
+ int interspaces,
+ Real, Real,
+ Interval x_extent,
+ Real left_shorten);
static bool has_interface (Grob*);
};
Stencil
-Ledger_line_spanner::brew_ledger_lines (Grob *me,
- int pos,
- int interspaces,
- Interval x_extent,
- Real left_shorten)
+Ledger_line_spanner::brew_ledger_lines (Grob *staff,
+ int pos,
+ int interspaces,
+ Real halfspace,
+ Real ledgerlinethickness,
+ Interval x_extent,
+ Real left_shorten)
{
- Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
- Real inter_f = Staff_symbol_referencer::staff_space (me)/2;
int line_count = ((abs (pos) < interspaces)
? 0
: (abs (pos) - interspaces) / 2);
Stencil stencil;
if (line_count)
{
- Real ledgerlinethickness =
- Staff_symbol::get_ledger_line_thickness (staff);
Real blotdiameter = ledgerlinethickness;
Interval y_extent =
Interval (-0.5*(ledgerlinethickness),
Lookup::round_filled_box (Box (x_extent, y_extent), blotdiameter);
Direction dir = (Direction)sign (pos);
- Real offs = (Staff_symbol_referencer::on_staffline (me, pos))
+ Real offs = (Staff_symbol_referencer::on_staffline (staff, pos))
? 0.0
- : -dir * inter_f;
+ : -dir * halfspace;
- offs += pos * inter_f;
+ offs += pos * halfspace;
for (int i = 0; i < line_count; i++)
{
Stencil ledger_line ((i == 0)
? proto_first_line
: proto_ledger_line
);
- ledger_line.translate_axis (-dir * inter_f * i * 2 + offs, Y_AXIS);
+ ledger_line.translate_axis (-dir * halfspace * i * 2 + offs, Y_AXIS);
stencil.add_stencil (ledger_line);
}
}
{
Spanner *me = dynamic_cast<Spanner*> (unsmob_grob (smob));
Link_array<Grob> heads (Pointer_group_interface__extract_grobs (me, (Grob*)0, "note-heads"));
+ Link_array<Grob> ambituses (Pointer_group_interface__extract_grobs (me, (Grob*)0, "ambituses"));
+ if (heads.is_empty () && ambituses.is_empty ())
+ return SCM_EOL;
+
Stencil ledgers;
Stencil default_ledger;
Grob * common[NO_AXES];
+
for (int i = X_AXIS; i < NO_AXES; i++)
- common[Axis (i)] = common_refpoint_of_array (heads, me, Axis(i));
+ {
+ Axis a = Axis (i);
+ common[a] = common_refpoint_of_array (heads, me, a);
+ common[a] = common_refpoint_of_array (ambituses, common[a], a);
+ for (int i = heads.size (); i--; )
+ if (Grob * g = unsmob_grob (me->get_property ("accidental-grob")))
+ common[a] = common[a]->common_refpoint (g, a);
+ }
- int interspaces = Staff_symbol_referencer::line_count (me)-1;
+ // find size of note heads.
+ Grob * staff = Staff_symbol_referencer::get_staff_symbol (me);
+ int interspaces = Staff_symbol::line_count (staff)-1;
Ledger_requests reqs;
- Real length_fraction = 0.25 * 2;
+ Real length_fraction = 0.25;
for (int i = heads.size (); i--; )
{
Item *h = dynamic_cast<Item*> (heads[i]);
int pos = Staff_symbol_referencer::get_rounded_position (h);
- if (abs (pos) > interspaces + 1)
+ if (abs (pos) > interspaces)
{
Interval head_extent = h->extent (common[X_AXIS], X_AXIS);
- Interval ledger_extent = Interval (head_extent.linear_combination (-1 - length_fraction),
- head_extent.linear_combination (1 + length_fraction));
+ Interval ledger_extent = head_extent;
+ head_extent.widen (length_fraction * head_extent.length ());
Direction vdir = Direction (sign (pos));
int rank = Paper_column::get_rank (h->get_column ());
}
}
- Real gap = robust_scm2double (me->get_property ("gap"), 0.15);
+ // determine maximum size for non-colliding ledger.
+ Real gap = robust_scm2double (me->get_property ("gap"), 0.1);
Ledger_requests::iterator last (reqs.end ());
for (Ledger_requests::iterator i (reqs.begin ());
i != reqs.end (); last = i++)
Direction d = DOWN;
do
{
- if (abs (last->second[d].position_) > interspaces + 1
- && abs (i->second[d].position_) > interspaces + 1)
+ if (abs (last->second[d].position_) > interspaces
+ && abs (i->second[d].position_) > interspaces)
{
Real center =
(last->second[d].head_extent_[RIGHT]
{
Ledger_request &lr = ((which == LEFT) ? *last : *i).second[d];
+ // due tilt of quarter note-heads
+ bool both =
+ (abs (last->second[d].position_) > interspaces + 1
+ && abs (i->second[d].position_) > interspaces + 1);
- // due tilt of quarter note-heads
- Real excentricity = 0; //.1;
- Real limit = (center + which * gap/2 + excentricity);
+ Real limit = (center + (both? which * gap/2 : 0));
lr.ledger_extent_.elem_ref (-which)
= which * (which * lr.ledger_extent_[-which] >? which * limit);
}
while (flip (&d) != DOWN);
}
- for (Ledger_requests::const_iterator i (reqs.begin ());
- i != reqs.end (); i++)
+ // create ledgers for note heads
+ Real ledgerlinethickness =
+ Staff_symbol::get_ledger_line_thickness (staff);
+ Real halfspace = Staff_symbol::staff_space (me)/2;
+ for (int i = heads.size (); i--; )
{
- Direction d = DOWN;
- do
+ Item *h = dynamic_cast<Item*> (heads[i]);
+
+ int pos = Staff_symbol_referencer::get_rounded_position (h);
+ if (abs (pos) > interspaces + 1)
{
- Ledger_request lr = (*i).second[d];
- ledgers.add_stencil (brew_ledger_lines (me,
- lr.position_,
- interspaces,
- lr.ledger_extent_,
- 0.0));
+ Interval ledger_size = h->extent (common[X_AXIS], X_AXIS);
+ ledger_size.widen (ledger_size.length ()* length_fraction);
+
+ Interval max_size = reqs[Paper_column::get_rank (h->get_column ())][Direction (sign(pos))].ledger_extent_;
+
+ ledger_size.intersect (max_size);
+ Real left_shorten =0.0;
+ if (Grob * g = unsmob_grob (h->get_property ("accidental-grob")))
+ {
+ Real d =
+ linear_combination (Drul_array<Real> (h->extent (common[X_AXIS], X_AXIS)[LEFT],
+ g->extent (common[X_AXIS], X_AXIS)[RIGHT]),
+
+ 0.5);
+
+ left_shorten = (-ledger_size[LEFT] + d) >? 0 ;
+
+ /*
+ TODO: shorten 2 ledger lines for the case natural +
+ downstem.
+ */
+
+ }
+
+ ledgers.add_stencil (brew_ledger_lines (staff, pos, interspaces,
+ halfspace,
+ ledgerlinethickness,
+ ledger_size,
+ left_shorten));
}
- while (flip (&d) != DOWN);
}
+ /* create ledgers for ambitus.
+
+ TODO: split off separate function
+
+ */
+ for (int i = ambituses.size (); i--; )
+ {
+ Item *a = dynamic_cast<Item*> (ambituses[i]);
+ Interval x_ext = ambituses[i]->extent (common[X_AXIS], X_AXIS);
+ x_ext.widen (length_fraction * x_ext.length ());
+
+ Slice ps (Ambitus::get_positions (a));
+ Direction d = DOWN;
+ do
+ {
+ if (abs (ps[d]) > interspaces + 1)
+ ledgers.add_stencil (brew_ledger_lines (staff, ps[d], interspaces,
+ halfspace,
+ ledgerlinethickness,
+ x_ext, 0.0));
+ }
+ while (flip (&d) != DOWN);
+ }
+
ledgers.translate_axis (-me->relative_coordinate (common[X_AXIS], X_AXIS),
X_AXIS);
return stencil;
}
-void
-add_ledger_lines (Grob *me, Stencil *out, int pos, Real offs,
- bool ledger_take_space)
-{
- int interspaces = Staff_symbol_referencer::line_count (me)-1;
- if (abs (pos) - interspaces > 1)
- {
- Interval hd = out->extent (X_AXIS);
- Real left_ledger_protusion = hd.length ()/4;
- Real right_ledger_protusion = left_ledger_protusion;
-
- Interval l_extents = Interval (hd[LEFT] - left_ledger_protusion,
- hd[RIGHT] + right_ledger_protusion);
- Stencil ledger_lines =
- Note_head::brew_ledger_lines (me, pos, interspaces,
- l_extents,0,
- ledger_take_space);
- ledger_lines.translate_axis (offs, Y_AXIS);
- out->add_stencil (ledger_lines);
- }
-}
-
Stencil
internal_brew_primitive (Grob *me, bool ledger_take_space)
{
}
int pos = Staff_symbol_referencer::get_rounded_position (me);
- add_ledger_lines (me, &out, pos, 0, ledger_take_space);
if (primitive & MLP_FLEXA)
{
pos += delta_pitch;
- add_ledger_lines (me, &out, pos, 0.5*delta_pitch, ledger_take_space);
}
return out;
#include "output-def.hh"
/*
- Note_head contains the code for printing note heads.
-
- Ledger lines:
-
- It also contains the ledger lines, for historical reasons. Ledger
- lines are somewhat of a PITA. In some cases, they take up no space, in
- some cases they don't:
-
- DO take space:
-
- - when ledgered notes are juxtaposed: there should be some white
- space between the ledger lines.
-
- - when accidentals are near: the accidentals should not be on the
- ledger lines
-
- [both tips by Heinz Stolba from Universal Edition].
-
- DO NOT take space into account:
-
- - for basically everything else, e.g. swapping ledgered notes on
- clustered chords, spacing between ledgered and unledgered notes.
-
- TODO: fix this. It is not feasible to have a special grob for
- ledgers, since you basically don't know if there will be ledgers,
- unless you know at interpretation phase already 1. the Y-position,
- 2. the number of staff lines. It's not yet specced when both pieces
- of information are there, so for now, it is probably better to build
- special support for ledgers into the accidental and separation-item
- code.
-
- (Besides a separate ledger seems overkill. For what else would
- it be useful?)
-
+ clean up the mess left by ledger line handling.
*/
-
-/*
- TODO: ledger lines are also a property of the staff. Maybe move them
- to there?
- */
-Stencil
-Note_head::brew_ledger_lines (Grob *me,
- int pos,
- int interspaces,
- Interval x_extent,
- Real left_shorten,
- bool take_space)
-{
- Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
- Real inter_f = Staff_symbol_referencer::staff_space (me)/2;
- int line_count = ((abs (pos) < interspaces)
- ? 0
- : (abs (pos) - interspaces) / 2);
- Stencil stencil;
- if (line_count)
- {
- Real ledgerlinethickness =
- Staff_symbol::get_ledger_line_thickness (staff);
- Real blotdiameter = ledgerlinethickness;
- Interval y_extent =
- Interval (-0.5*(ledgerlinethickness),
- +0.5*(ledgerlinethickness));
- Stencil proto_ledger_line =
- Lookup::round_filled_box (Box (x_extent, y_extent), blotdiameter);
-
- x_extent[LEFT] += left_shorten;
- Stencil proto_first_line =
- Lookup::round_filled_box (Box (x_extent, y_extent), blotdiameter);
-
- if (!take_space)
- {
- proto_ledger_line.set_empty (true);
- proto_first_line.set_empty (true);
- }
-
- Direction dir = (Direction)sign (pos);
- Real offs = (Staff_symbol_referencer::on_staffline (me, pos))
- ? 0.0
- : -dir * inter_f;
-
- for (int i = 0; i < line_count; i++)
- {
- Stencil ledger_line ((i == 0)
- ? proto_first_line
- : proto_ledger_line
- );
- ledger_line.translate_axis (-dir * inter_f * i * 2 + offs, Y_AXIS);
- stencil.add_stencil (ledger_line);
- }
- }
-
- return stencil;
-}
-
-Stencil
-internal_print (Grob *me, bool with_ledgers)
+static Stencil
+internal_print (Grob *me)
{
SCM style = me->get_property ("style");
if (!ly_c_symbol_p (style))
me->warning (_f ("note head `%s' not found", font_char.to_str0 ()));
}
-#if 0
- int interspaces = Staff_symbol_referencer::line_count (me)-1;
- int pos = Staff_symbol_referencer::get_rounded_position (me);
- if (with_ledgers && interspaces >= 0
- && abs (pos) - interspaces > 1)
- {
- Interval ledger_size = out.extent (X_AXIS);
- ledger_size.widen ( ledger_size.length ()/4);
-
- Real left_shorten =0.0;
- if (Grob * g = unsmob_grob (me->get_property ("accidental-grob")))
- {
- /*
- make a little room for accidentals.
-
- TODO: this will look silly if a chord has ledger lines,
- and only the bottom note has an accidental.
- */
-
- Grob *common = g->common_refpoint (me, X_AXIS);
- Real d =
- linear_combination (Drul_array<Real> (me->extent (common, X_AXIS)[LEFT],
- g->extent (common, X_AXIS)[RIGHT]),
-
- 0.5);
-
- left_shorten = (-ledger_size[LEFT] + d) >? 0 ;
-
- /*
- TODO: shorten 2 ledger lines for the case natural +
- downstem.
- */
- }
-
- out.add_stencil (Note_head::brew_ledger_lines (me, pos, interspaces,
- ledger_size,
- left_shorten,
- false));
- }
-#endif
-
return out;
}
{
Grob *me = unsmob_grob (smob);
- /*
- ledgers don't take space. See top of file.
- */
- return internal_print (me, true).smobbed_copy ();
+ return internal_print (me).smobbed_copy ();
}
/*
SCM brewer = me->get_property ("print-function");
if (brewer == Note_head::print_proc)
{
- Stencil mol = internal_print (me, false);
+ Stencil mol = internal_print (me);
if (!mol.is_empty ())
return mol.extent (a);
Box bx (Interval (0, 1.0), Interval (-0.5, 0.5));
Stencil m (bx, at);
- int pos = Staff_symbol_referencer::get_rounded_position (me);
- int interspaces = Staff_symbol_referencer::line_count (me)-1;
- if (abs (pos) - interspaces > 1)
- {
- Interval hd = m.extent (X_AXIS);
- hd.widen ( hd.length ()/4);
- m.add_stencil (brew_ledger_lines (me, pos, interspaces, hd, 0, false));
- }
-
return m.smobbed_copy ();
}
--- /dev/null
+/*
+ pitch-interval.cc -- implement Pitch_interval
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#include "pitch-interval.hh"
+#include "interval.tcc"
+
+
+Pitch_interval::Pitch_interval (Pitch p1, Pitch p2)
+{
+ elem_ref(LEFT) = p1;
+ elem_ref(RIGHT) = p2;
+}
+
+
+Pitch_interval::Pitch_interval ()
+{
+ elem_ref(LEFT) = Pitch (100,0,0);
+ elem_ref(RIGHT) = Pitch (-100,0,0);
+}
+
+
+bool
+Pitch_interval::is_empty () const
+{
+ return elem(LEFT) > elem(RIGHT);
+}
+
+
+void
+Pitch_interval::add_point (Pitch p)
+{
+ if (elem_ref(LEFT) > p)
+ elem_ref(LEFT) = p;
+ if (elem_ref(RIGHT) < p)
+ elem_ref(RIGHT) = p;
+}
Real thick = thickness (me);
Grob *hed = support_head (me);
- Real w = Note_head::head_extent (hed,X_AXIS)[dir];
+ Real w = Note_head::head_extent (hed, X_AXIS)[dir];
for (int i = 0; i < heads.size (); i++)
heads[i]->translate_axis (w - Note_head::head_extent (heads[i],
X_AXIS)[dir],
return Lookup::round_filled_box (join_box, blotdiameter);
}
-void
-vaticana_add_ledger_lines (Grob *me, Stencil *out, int pos, Real offs,
- bool ledger_take_space)
-{
- int interspaces = Staff_symbol_referencer::line_count (me)-1;
- if (abs (pos) - interspaces > 1)
- {
- Interval hd = out->extent (X_AXIS);
- Real left_ledger_protusion = hd.length ()/4;
- Real right_ledger_protusion = left_ledger_protusion;
-
- Interval l_extents = Interval (hd[LEFT] - left_ledger_protusion,
- hd[RIGHT] + right_ledger_protusion);
- Stencil ledger_lines =
- Note_head::brew_ledger_lines (me, pos, interspaces,
- l_extents, 0,
- ledger_take_space);
- ledger_lines.translate_axis (offs, Y_AXIS);
- out->add_stencil (ledger_lines);
- }
-}
-
Stencil
vaticana_brew_primitive (Grob *me, bool ledger_take_space)
{
out.add_stencil (join);
}
- vaticana_add_ledger_lines (me, &out, pos, 0, ledger_take_space);
- if (!String::compare (glyph_name, "flexa"))
- {
- pos += flexa_height;
- vaticana_add_ledger_lines (me, &out, pos, 0.5*flexa_height,
- ledger_take_space);
- }
-
return out;
}
(after-line-breaking-callback ,procedure? "This procedure is called after line breaking. Its return value is ignored.")
(all-elements ,grob-list? "list of all grobs in this line. Its
function is to protect objects from being garbage collected.")
+ (ambituses ,grob-list? "list of Ambitus objects")
(arpeggio ,ly:grob? "pointer to arpeggio object.")
(beam ,ly:grob? "pointer to the beam, if applicable.")
(center-element ,ly:grob? "grob which will be at the center of
))
(meta . ((interfaces . (ambitus-interface staff-symbol-referencer-interface break-aligned-interface item-interface font-interface))))
))
-
+ (AmbitusNoteHead
+ . (
+ (style . default)
+ (breakable . #t)
+ (print-function . ,Note_head::print)
+ (break-align-symbol . ambitus)
+ (glyph-name-procedure . ,find-notehead-symbol)
+ (X-extent-callback . ,Note_head::extent)
+ (Y-extent-callback . ,Note_head::extent)
+ (Y-offset-callbacks . (,Staff_symbol_referencer::callback))
+ (meta . ((interfaces . (font-interface note-head-interface ambitus-interface staff-symbol-referencer-interface item-interface ))))
+ ))
+
(Arpeggio
. (
(X-extent-callback . ,Arpeggio::width_callback)
))
(LedgerLineSpanner
. (
+ (print-function . ,Ledger_line_spanner::print)
+ (X-extent-callback . #f)
+ (Y-extent-callback . #f)
(print-function . ,Ledger_line_spanner::print)
(meta . ((interfaces . (spanner-interface ledger-line-interface))))
))