From: fred Date: Mon, 30 Oct 2000 11:55:45 +0000 (+0000) Subject: lilypond-1.3.101 X-Git-Tag: release/1.5.59~5722 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=9053b0d6c3f232f5020cf5a7d0c13c7135a80fdc;p=lilypond.git lilypond-1.3.101 --- diff --git a/lily/custos-engraver.cc b/lily/custos-engraver.cc new file mode 100644 index 0000000000..5f15194535 --- /dev/null +++ b/lily/custos-engraver.cc @@ -0,0 +1,147 @@ +/* + custos-engraver.cc -- implement Custos_engraver + + source file of the GNU LilyPond music typesetter + + (C) 2000 Juergen Reuter , + + Han-Wen Nienhuys + +*/ + +#include "engraver.hh" +#include "bar.hh" +#include "item.hh" +#include "note-head.hh" +#include "staff-symbol-referencer.hh" +#include "warn.hh" +#include "musical-request.hh" + +/* + This class implements an engraver for custos symbols. +*/ +class Custos_engraver : public Engraver +{ +public: + Custos_engraver(); + virtual void do_post_move_processing(); + virtual void acknowledge_element(Score_element_info); + virtual void do_process_music (); + virtual void process_acknowledged (); + virtual void do_pre_move_processing (); + virtual void do_removal_processing (); + VIRTUAL_COPY_CONS(Translator); + +private: + Item * create_custos(); + bool custos_permitted; + Link_array custos_arr_; + Array pitches_; +}; + +Custos_engraver::Custos_engraver () +{ + custos_permitted = false; +} + + +void +Custos_engraver::do_pre_move_processing() +{ + /* + delay typeset until we're at the next moment, so we can silence custodes at the end of the piece. + */ +} + +void +Custos_engraver::do_post_move_processing () +{ + for (int i = custos_arr_.size (); i--;) + { + typeset_element (custos_arr_[i]); + } + custos_arr_.clear (); + pitches_.clear (); + + custos_permitted = false; +} + + +/* + TODO check if this works with forced bar lines? + */ +void +Custos_engraver::do_process_music () +{ + if (gh_string_p (get_property( "whichBar"))) + custos_permitted = true; +} + +void +Custos_engraver::acknowledge_element (Score_element_info info) +{ + Item *item = dynamic_cast (info.elem_l_); + if (item) + { + if (Bar::has_interface (info.elem_l_)) + custos_permitted = true; + else if (Note_head::has_interface (info.elem_l_)) + { + + /* + ideally, we'd do custos->set_parent (Y_AXIS, notehead), + but since the note head lives on the other system, we can't + + So we copy the position from the note head pitch. We + don't look at the staff-position, since we can't be sure + whether Clef_engraver already applied a vertical shift. + */ + + pitches_.push (dynamic_cast (info.req_l_)->pitch_); + } + } +} + +void +Custos_engraver::process_acknowledged () +{ + if (custos_permitted) + { + for (int i = pitches_.size (); i--;) + { + Item *c = create_custos (); + + c->set_elt_property ("staff-position", + gh_int2scm (pitches_[i].steps ())); + + } + + pitches_.clear (); + } +} + +Item* +Custos_engraver::create_custos() +{ + SCM basicProperties = get_property ("Custos"); + Item* custos = new Item (basicProperties); + + announce_element (custos, 0); + custos_arr_.push (custos); + + return custos; +} + +void +Custos_engraver::do_removal_processing () +{ + for (int i = custos_arr_.size (); i--;) + { + custos_arr_[i]->suicide (); + typeset_element (custos_arr_[i]); + } + custos_arr_.clear (); +} + +ADD_THIS_TRANSLATOR (Custos_engraver); + diff --git a/lily/custos.cc b/lily/custos.cc new file mode 100644 index 0000000000..24091d6646 --- /dev/null +++ b/lily/custos.cc @@ -0,0 +1,180 @@ +/* + custos.cc -- implement Custos + + source file of the GNU LilyPond music typesetter + + (C) 2000 Juergen Reuter +*/ + +/* TODO: + + - merge create_ledger_line () and Note_head::create_ledger_line() + + + - rewrite create_ledger_line() to support short and thin ledger lines + + - do not show if a clef change immediately follows in the next line + + - make custos direction control configurable + + - decide: do or do not print custos if the next line starts with a rest + +*/ + + +#include +#include "staff-symbol-referencer.hh" +#include "custos.hh" +#include "molecule.hh" +#include "lookup.hh" +#include "debug.hh" +#include "note-head.hh" +#include "item.hh" +#include "font-interface.hh" + +/* + This function is a patched and hopefully much more understandable + rewrite of Note_head::ledger_line(). It still has some + bugs/limitations: + * + (1) The term thick/2 probably should be thick*2 (probably a bug, + see the code below). + * + (2) The minimal width of the resulting ledger line equals the width + of the noteheads-ledgerending symbol (a limitation): + * + (---- left ledger ending + ----) right ledger ending + (---) resulting ledger line (just ok) + * + If x_extent ("xwid" in Note_head) is less than the width of the + ledger ending, the width of the total ledger line is even *greater* + than the width of a ledger ending (I would call this a bug). In + the below code, the condition "if (x_extent.length() > + slice_x_extent.length())" avoids outputting the left ending in such + cases (rather a silly workaround, but better than nothing). + * + (---- left ledger ending + ----) right ledger ending + (-) desired ledger line + ------- resulting ledger line (too long) + ----) resulting ledger line with additional "if" (still too long) + * + The algorithm works properly only for a desired ledger line width + greater than the width of the ledger ending: + * + (---- left ledger ending + ----) right ledger ending + (------) desired ledger line + (------) resulting ledger line (ok) + * + * (3) The thickness of the ledger line is fixed (limitation). + */ +Molecule create_ledger_line (Interval x_extent, Score_element *me) +{ + Molecule line; + Molecule slice = Font_interface::get_default_font (me)->find_by_name ("noteheads-ledgerending"); + Interval slice_x_extent = slice.extent(X_AXIS); + Interval slice_y_extent = slice.extent(Y_AXIS); + + // Create left ending of ledger line. + Molecule left_ending = slice; + left_ending.translate_axis (x_extent[LEFT] - slice_x_extent[LEFT], X_AXIS); + if (x_extent.length() > slice_x_extent.length()) + line.add_molecule (left_ending); + + // Create right ending of ledger line. + Molecule right_ending = slice; + right_ending.translate_axis (x_extent[RIGHT] - slice_x_extent[RIGHT], + X_AXIS); + line.add_molecule (right_ending); + + // Fill out space between left and right ending of ledger line by + // lining up a series of slices in a row between them. + Molecule fill_out_slice = left_ending; + Real thick = slice_y_extent.length(); + Real delta_x = slice_x_extent.length () - thick; + Real xpos = x_extent [LEFT] + 2*delta_x + thick/2; // TODO: check: thick*2? + while (xpos <= x_extent[RIGHT]) + { + fill_out_slice.translate_axis (delta_x, X_AXIS); + line.add_molecule (fill_out_slice); + xpos += delta_x; + } + + return line; +} + +void add_streepjes(Score_element* me, + int pos, + int interspaces, + Molecule* custos_p_) +{ + // TODO: This is (almost) duplicated code (see + // Note_head::brew_molecule). Junk me. + Real inter_f = Staff_symbol_referencer::staff_space (me)/2; + int streepjes_i = abs (pos) < interspaces + ? 0 + : (abs(pos) - interspaces) /2; + if (streepjes_i) + { + Direction dir = (Direction)sign (pos); + Molecule ledger_line (create_ledger_line (custos_p_->extent (X_AXIS), + me)); + ledger_line.set_empty (true); + Real offs = (Staff_symbol_referencer::on_staffline (me)) + ? 0.0 + : -dir * inter_f; + for (int i = 0; i < streepjes_i; i++) + { + Molecule streep (ledger_line); + streep.translate_axis (-dir * inter_f * i * 2 + offs, + Y_AXIS); + custos_p_->add_molecule (streep); + } + } +} + +MAKE_SCHEME_CALLBACK(Custos,brew_molecule,1); +SCM +Custos::brew_molecule (SCM smob) +{ + Item *me = (Item *)unsmob_element (smob); + SCM scm_style = me->get_elt_property ("style"); + + if (gh_string_p (scm_style)) + { + String style = ly_scm2string (scm_style); + + String idx = "custodes-"; + int interspaces = Staff_symbol_referencer::line_count (me)-1; + + Real pos = Staff_symbol_referencer::position_f (me); + + if (pos > (interspaces/2 + 1)) // TODO: make this rule configurable + idx += "r"; + idx += style; + Molecule molecule + = Font_interface::get_default_font (me)->find_by_name (idx); + if (molecule.empty_b()) + { + String message = "unknown custos style: `" + style + "'"; + warning(_ (message.ch_C())); + return SCM_EOL; + } + else + { + add_streepjes(me, (int)pos, interspaces, &molecule); + SCM result = molecule.create_scheme(); + return result; + } + } + else + return SCM_EOL; +} + +bool +Custos::has_interface (Score_element*m) +{ + return m && m->has_interface (ly_symbol2scm ("custos-interface")); +} diff --git a/lily/include/custos.hh b/lily/include/custos.hh new file mode 100644 index 0000000000..d962ef975f --- /dev/null +++ b/lily/include/custos.hh @@ -0,0 +1,21 @@ +/* + custos.hh + + source file of the GNU LilyPond music typesetter + + (C) 2000 Juergen Reuter +*/ + +#ifndef CUSTOS_HH +#define CUSTOS_HH + +#include "lily-guile.hh" + +struct Custos +{ + DECLARE_SCHEME_CALLBACK(brew_molecule, (SCM )); + static bool has_interface (Score_element*); +}; + +#endif // CUSTOS_HH +