From: Han-Wen Nienhuys Date: Wed, 17 Apr 2002 11:12:31 +0000 (+0000) Subject: new file. X-Git-Tag: release/1.5.53~13 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=b55303a78f027962dbebf62dbe396325f3b6e1a5;p=lilypond.git new file. --- diff --git a/lily/ligature-bracket-engraver.cc b/lily/ligature-bracket-engraver.cc new file mode 100644 index 0000000000..d933448862 --- /dev/null +++ b/lily/ligature-bracket-engraver.cc @@ -0,0 +1,193 @@ +/* + ligature-bracket-engraver.cc -- implement Ligature__bracket_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2002 Juergen Reuter + + */ +#include "engraver.hh" +#include "musical-request.hh" +#include "warn.hh" +#include "drul-array.hh" +#include "item.hh" +#include "spanner.hh" +#include "score-engraver.hh" +#include "note-head.hh" +#include "stem.hh" +#include "rest.hh" + +class Ligature_bracket_engraver : public Engraver +{ + Drul_array reqs_drul_; + + Spanner *finished_ligature_bracket_p_; + Spanner *ligature_bracket_p_; + Span_req *prev_start_req_; + + // moment where ligature started. + Moment ligature_start_mom_; + Grob *last_bound; + +protected: + virtual void stop_translation_timestep (); + virtual void start_translation_timestep (); + virtual void finalize (); + + virtual void acknowledge_grob (Grob_info); + virtual bool try_music (Music*); + virtual void process_music (); + +public: + TRANSLATOR_DECLARATIONS(Ligature_bracket_engraver); + +private: + void typeset_ligature_bracket (); +}; + + +Ligature_bracket_engraver::Ligature_bracket_engraver () +{ + ligature_bracket_p_ = 0; + finished_ligature_bracket_p_ = 0; + reqs_drul_[LEFT] = reqs_drul_[RIGHT] = 0; + prev_start_req_ = 0; + last_bound = 0; +} + +bool +Ligature_bracket_engraver::try_music (Music *m) +{ + if (Span_req *req_ = dynamic_cast (m)) + { + if (scm_equal_p (req_->get_mus_property ("span-type"), + ly_str02scm ("abort")) == SCM_BOOL_T) + { + reqs_drul_[START] = 0; + reqs_drul_[STOP] = 0; + if (ligature_bracket_p_) + ligature_bracket_p_->suicide (); + ligature_bracket_p_ = 0; + } + else if (scm_equal_p (req_->get_mus_property ("span-type"), + ly_str02scm ("ligature-bracket")) == SCM_BOOL_T) + { + Direction d = req_->get_span_dir (); + reqs_drul_[d] = req_; + return true; + } + } + return false; +} + +void +Ligature_bracket_engraver::process_music () +{ + if (reqs_drul_[STOP]) + { + if (!ligature_bracket_p_) + reqs_drul_[STOP]->origin ()->warning (_ ("can't find start of ligature")); + else + { + if (!last_bound) + { + reqs_drul_[STOP]->origin ()->warning (_ ("no right bound")); + } + else + { + ligature_bracket_p_->set_bound (RIGHT, last_bound); + } + } + prev_start_req_ = 0; + finished_ligature_bracket_p_ = ligature_bracket_p_; + ligature_bracket_p_ = 0; + } + last_bound = unsmob_grob (get_property ("currentMusicalColumn")); + + if (ligature_bracket_p_) + { + // TODO: maybe forbid breaks only if not transcribing + top_engraver ()->forbid_breaks (); + } + if (reqs_drul_[START]) + { + if (ligature_bracket_p_) + { + reqs_drul_[START]->origin ()->warning (_ ("already have a ligature")); + return; + } + + prev_start_req_ = reqs_drul_[START]; + ligature_bracket_p_ = new Spanner (get_property ("LigatureBracket")); + + Grob *bound = unsmob_grob (get_property ("currentMusicalColumn")); + if (!bound) + { + reqs_drul_[START]->origin ()->warning (_ ("no left bound")); + } + else + { + ligature_bracket_p_->set_bound (LEFT, bound); + } + + ligature_start_mom_ = now_mom (); + + announce_grob(ligature_bracket_p_, reqs_drul_[START]->self_scm()); + } +} + +void +Ligature_bracket_engraver::start_translation_timestep () +{ + reqs_drul_[START] = 0; + reqs_drul_[STOP] = 0; +} + +void +Ligature_bracket_engraver::typeset_ligature_bracket () +{ + if (finished_ligature_bracket_p_) + { + typeset_grob (finished_ligature_bracket_p_); + finished_ligature_bracket_p_ = 0; + } +} + +void +Ligature_bracket_engraver::stop_translation_timestep () +{ + typeset_ligature_bracket (); +} + +void +Ligature_bracket_engraver::finalize () +{ + typeset_ligature_bracket (); + if (ligature_bracket_p_) + { + prev_start_req_->origin ()->warning (_ ("unterminated ligature")); + ligature_bracket_p_->suicide (); + } +} + +void +Ligature_bracket_engraver::acknowledge_grob (Grob_info info) +{ + if (ligature_bracket_p_) + { + if (Rest::has_interface (info.grob_l_)) + { + reqs_drul_[START]->origin ()->warning (_ ("ligature may not contain rest; ignoring rest")); + prev_start_req_->origin ()->warning (_ ("ligature was started here")); + // TODO: maybe better should stop ligature here rather than + // ignoring the rest? + } + } +} + +ENTER_DESCRIPTION(Ligature_bracket_engraver, +/* descr */ "Handles Ligature_requests by engraving Ligature brackets.", +/* creats*/ "LigatureBracket", +/* acks */ "rest-interface", +/* reads */ "", +/* write */ ""); diff --git a/lily/ligature-bracket.cc b/lily/ligature-bracket.cc new file mode 100644 index 0000000000..2e7d816fbc --- /dev/null +++ b/lily/ligature-bracket.cc @@ -0,0 +1,145 @@ +/* + ligature-bracket.cc -- implement Ligature_bracket + + source file of the GNU LilyPond music typesetter + + (c) 2002 Juergen Reuter +*/ + +#include "ligature-bracket.hh" +#include "item.hh" +#include "paper-def.hh" +#include "spanner.hh" +#include "staff-symbol-referencer.hh" +#include "lookup.hh" +#include "box.hh" + +static Molecule +brew_edge (Direction dir, Real thickness, Real width, Real height, + Real blotdiameter) +{ + Molecule hline = Lookup::roundfilledbox (Box (Interval (0, width), + Interval (0, thickness)), + blotdiameter); + hline.translate_axis (height - thickness, Y_AXIS); + + Molecule vline = Lookup::roundfilledbox (Box (Interval (0, thickness), + Interval (0, height)), + blotdiameter); + if (dir == RIGHT) + { + vline.translate_axis (width - thickness, X_AXIS); + } + + Molecule edge = Molecule (); + edge.add_molecule (hline); + edge.add_molecule (vline); + return edge; +} + +MAKE_SCHEME_CALLBACK (Ligature_bracket, brew_molecule, 1); +SCM +Ligature_bracket::brew_molecule (SCM smob) +{ + Grob *me = unsmob_grob (smob); + Spanner *spanner = dynamic_cast (me); + Real blotdiameter = me->paper_l ()->get_var ("blotdiameter"); + Real staff_space = Staff_symbol_referencer::staff_space (me); + + Real thickness = me->paper_l ()->get_var ("linethickness"); + SCM grob_thickness = me->get_grob_property ("thickness"); + if (gh_number_p (grob_thickness)) + thickness *= gh_scm2double (grob_thickness); + + SCM edge_width_scm = me->get_grob_property ("width"); + Real edge_width; + if (gh_number_p (edge_width_scm)) + { + edge_width = gh_scm2double (edge_width_scm); + } + else + { + edge_width = 0.75; + } + edge_width *= staff_space; + + SCM edge_height_scm = me->get_grob_property ("height"); + Real edge_height; + if (gh_number_p (edge_height_scm)) + { + edge_height = gh_scm2double (edge_height_scm); + } + else + { + edge_height = 0.5; + } + edge_height *= staff_space; + + Item* left_bound = spanner->get_bound (LEFT); + Item* right_bound = spanner->get_bound (RIGHT); + + Molecule bracket = Molecule (); + + Real y_min_offs = + 0.5 * Staff_symbol_referencer::line_count (me) * staff_space; + Real y_left_offs = y_min_offs; + Real y_right_offs = y_min_offs; + + Real left_bound_left_extent = 0; + + if (left_bound) + { + Molecule left_edge = + brew_edge (LEFT, thickness, edge_width, edge_height, blotdiameter); + Grob *left_common_x = me->common_refpoint (left_bound, X_AXIS); + left_bound_left_extent = + left_bound->extent (left_common_x, X_AXIS)[LEFT]; + left_edge.translate_axis (left_bound_left_extent, X_AXIS); + bracket.add_molecule (left_edge); + Grob *left_common_y = me->common_refpoint (left_bound, Y_AXIS); + y_left_offs = + max(y_left_offs, left_bound->extent (left_common_y, Y_AXIS)[UP]); + } + else + { + me->warning (_ ("no left bound")); + } + + if (right_bound) + { + Molecule right_edge = + brew_edge (RIGHT, thickness, edge_width, edge_height, blotdiameter); + Grob *staff_symbol = Staff_symbol_referencer::staff_symbol_l (me); + Grob *right_common_bound_x = + right_bound->common_refpoint (staff_symbol, X_AXIS); + + Real left_offs = 0; + if (left_bound) + { + Grob *left_common_bound_x = + left_bound->common_refpoint (staff_symbol, X_AXIS); + left_offs = left_bound->extent (left_common_bound_x, X_AXIS)[LEFT]; + } + + Real right_offs = + right_bound->extent (right_common_bound_x, X_AXIS)[RIGHT]; + + right_edge.translate_axis (+ right_offs + - left_offs + + left_bound_left_extent + - edge_width, + X_AXIS); + bracket.add_molecule (right_edge); + Grob *right_common_y = me->common_refpoint (right_bound, Y_AXIS); + y_right_offs = + max(y_right_offs, right_bound->extent (right_common_y, Y_AXIS)[UP]); + } + else + { + me->warning (_ ("no left bound")); + } + + bracket.translate_axis (max (y_left_offs, y_right_offs), Y_AXIS); + + return bracket.smobbed_copy (); +}