X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Faccidental-placement.cc;h=1c7d356cc93f1b17ce289277f99520745de6cc87;hb=5b4b0d6e9a197e8f9eb085b7c2ad78b8be3e5cfc;hp=f8000479883144573436d5dfb4ad73b9ee897001;hpb=9d4a5bbc9687aef811a60aabd9cb839412984e96;p=lilypond.git diff --git a/lily/accidental-placement.cc b/lily/accidental-placement.cc index f800047988..1c7d356cc9 100644 --- a/lily/accidental-placement.cc +++ b/lily/accidental-placement.cc @@ -3,20 +3,22 @@ source file of the GNU LilyPond music typesetter - (c) 2002--2006 Han-Wen Nienhuys + (c) 2002--2008 Han-Wen Nienhuys */ - #include "accidental-placement.hh" -#include "skyline.hh" + +#include "item.hh" +#include "rhythmic-head.hh" +#include "accidental-interface.hh" #include "music.hh" -#include "pitch.hh" -#include "warn.hh" +#include "note-collision.hh" #include "note-column.hh" #include "pointer-group-interface.hh" -#include "note-collision.hh" -#include "accidental-interface.hh" +#include "skyline.hh" +#include "stream-event.hh" +#include "warn.hh" void @@ -26,10 +28,10 @@ Accidental_placement::add_accidental (Grob *me, Grob *a) a->set_property ("X-offset", Grob::x_parent_positioning_proc); SCM cause = a->get_parent (Y_AXIS)->get_property ("cause"); - Music *mcause = unsmob_music (cause); + Stream_event *mcause = unsmob_stream_event (cause); if (!mcause) { - programming_error ("note head has no music cause"); + programming_error ("note head has no event cause"); return; } @@ -57,8 +59,8 @@ Accidental_placement::add_accidental (Grob *me, Grob *a) */ void Accidental_placement::split_accidentals (Grob *accs, - Link_array__Grob_ *break_reminder, - Link_array__Grob_ *real_acc) + vector *break_reminder, + vector *real_acc) { for (SCM acs = accs->get_object ("accidental-grobs"); scm_is_pair (acs); acs = scm_cdr (acs)) @@ -66,53 +68,41 @@ Accidental_placement::split_accidentals (Grob *accs, { Grob *a = unsmob_grob (scm_car (s)); - if (unsmob_grob (a->get_object ("tie"))) + if (unsmob_grob (a->get_object ("tie")) + && !to_boolean (a->get_property ("forced"))) break_reminder->push_back (a); else real_acc->push_back (a); } } -/* - Accidentals are special, because they appear and disappear after - ties at will. -*/ -Interval -Accidental_placement::get_relevant_accidental_extent (Grob *me, - Item *item_col, - Grob *left_object) +vector +Accidental_placement::get_relevant_accidentals (vector const &elts, Grob *left) { - Link_array__Grob_ br, ra; - Link_array__Grob_ *which = 0; + vector br; + vector ra; + vector ret; + bool right = dynamic_cast (left)->break_status_dir () == RIGHT; - Accidental_placement::split_accidentals (me, &br, &ra); - concat (br, ra); - - if (dynamic_cast (left_object)->break_status_dir () == RIGHT) - which = &br; - else - which = &ra; - - Interval extent; - for (vsize i = 0; i < which->size (); i++) - extent.unite (which->at (i)->extent (item_col, X_AXIS)); - - if (!extent.is_empty ()) + for (vsize i = 0; i < elts.size (); i++) { - Real p = robust_scm2double (me->get_property ("left-padding"), 0.2); - extent[LEFT] -= p; - } + split_accidentals (elts[i], &br, &ra); + + ret.insert (ret.end (), ra.begin (), ra.end ()); - return extent; + if (right) + ret.insert (ret.end (), br.begin (), br.end ()); + } + return ret; } struct Accidental_placement_entry { - std::vector left_skyline_; - std::vector right_skyline_; + Skyline left_skyline_; + Skyline right_skyline_; Interval vertical_extent_; - std::vector extents_; - Link_array__Grob_ grobs_; + vector extents_; + vector grobs_; Real offset_; int notename_; Accidental_placement_entry () @@ -134,6 +124,12 @@ int ape_compare (Accidental_placement_entry *const &a, return sign (ape_priority (a) - ape_priority (b)); } +bool ape_less (Accidental_placement_entry *const &a, + Accidental_placement_entry *const &b) +{ + return ape_priority (a) < ape_priority (b); +} + int ape_rcompare (Accidental_placement_entry *const &a, Accidental_placement_entry *const &b) { @@ -149,11 +145,11 @@ int ape_rcompare (Accidental_placement_entry *const &a, placement */ void -stagger_apes (Link_array__Accidental_placement_entry_ *apes) +stagger_apes (vector *apes) { - Link_array__Accidental_placement_entry_ asc = *apes; + vector asc = *apes; - vector_sort (asc, &ape_compare); + vector_sort (asc, &ape_less); apes->clear (); @@ -217,7 +213,7 @@ stagger_apes (Link_array__Accidental_placement_entry_ *apes) */ -MAKE_SCHEME_CALLBACK(Accidental_placement, calc_positioning_done, 1); +MAKE_SCHEME_CALLBACK (Accidental_placement, calc_positioning_done, 1); SCM Accidental_placement::calc_positioning_done (SCM smob) { @@ -225,6 +221,8 @@ Accidental_placement::calc_positioning_done (SCM smob) if (!me->is_live ()) return SCM_BOOL_T; + me->set_property ("positioning-done", SCM_BOOL_T); + SCM accs = me->get_object ("accidental-grobs"); if (!scm_is_pair (accs)) return SCM_BOOL_T; @@ -233,7 +231,7 @@ Accidental_placement::calc_positioning_done (SCM smob) TODO: there is a bug in this code. If two accs are on the same Y-position, they share an Ape, and will be printed in overstrike. */ - Link_array__Accidental_placement_entry_ apes; + vector apes; for (SCM s = accs; scm_is_pair (s); s = scm_cdr (s)) { Accidental_placement_entry *ape = new Accidental_placement_entry; @@ -251,7 +249,7 @@ Accidental_placement::calc_positioning_done (SCM smob) First we must extract *all* pointers. We can only determine extents if we're sure that we've found the right common refpoint */ - Link_array__Grob_ note_cols, heads; + vector note_cols, heads; for (vsize i = apes.size (); i--;) { Accidental_placement_entry *ape = apes[i]; @@ -292,29 +290,48 @@ Accidental_placement::calc_positioning_done (SCM smob) for (vsize i = note_cols.size (); i--;) concat (heads, extract_grob_array (note_cols[i], "note-heads")); - vector_sort (heads, default_compare); + vector_sort (heads, less ()); uniq (heads); + + vector stems; + for (vsize i = 0; i < heads.size (); i++) + { + if (Grob *s = Rhythmic_head::get_stem (heads[i])) + stems.push_back (s); + } + + vector_sort (stems, less ()); + uniq (stems); + common[Y_AXIS] = common_refpoint_of_array (heads, common[Y_AXIS], Y_AXIS); + common[Y_AXIS] = common_refpoint_of_array (stems, common[Y_AXIS], Y_AXIS); + + for (vsize i = 0; i < heads.size (); i++) + { + if (Grob *s = Rhythmic_head::get_stem (heads[i])) + { + stems.push_back (s); + common[Y_AXIS] = s->common_refpoint (common[Y_AXIS], Y_AXIS); + } + } + + vector_sort (stems, less ()); + uniq (stems); + for (vsize i = apes.size (); i--;) { Accidental_placement_entry *ape = apes[i]; - ape->left_skyline_ = empty_skyline (LEFT); - ape->right_skyline_ = empty_skyline (RIGHT); for (vsize j = apes[i]->grobs_.size (); j--;) { Grob *a = apes[i]->grobs_[j]; - - std::vector boxes = Accidental_interface::accurate_boxes (a, common); + vector boxes = Accidental_interface::accurate_boxes (a, common); ape->extents_.insert (ape->extents_.end (), boxes.begin (), boxes.end ()); - for (vsize j = boxes.size (); j--;) - { - insert_extent_into_skyline (&ape->left_skyline_, boxes[j], Y_AXIS, LEFT); - insert_extent_into_skyline (&ape->right_skyline_, boxes[j], Y_AXIS, RIGHT); - } } + ape->left_skyline_ = Skyline (ape->extents_, 0, Y_AXIS, LEFT); + ape->right_skyline_ = Skyline (ape->extents_, 0, Y_AXIS, RIGHT); } Interval total; @@ -332,41 +349,44 @@ Accidental_placement::calc_positioning_done (SCM smob) Accidental_placement_entry *head_ape = new Accidental_placement_entry; common[X_AXIS] = common_refpoint_of_array (heads, common[X_AXIS], X_AXIS); - std::vector head_skyline (empty_skyline (LEFT)); - std::vector head_extents; + + vector head_extents; for (vsize i = heads.size (); i--;) - { - Box b (heads[i]->extent (common[X_AXIS], X_AXIS), - heads[i]->extent (common[Y_AXIS], Y_AXIS)); + head_extents.push_back (Box (heads[i]->extent (common[X_AXIS], X_AXIS), + heads[i]->extent (common[Y_AXIS], Y_AXIS))); - insert_extent_into_skyline (&head_skyline, b, Y_AXIS, LEFT); + for (vsize i = 0; i < stems.size (); i ++) + { + int very_large = INT_MAX; + + head_extents.push_back (Box (stems[i]->extent (common[X_AXIS], X_AXIS), + stems[i]->pure_height (common[Y_AXIS], 0, very_large))); } - head_ape->left_skyline_ = head_skyline; + head_ape->left_skyline_ = Skyline (head_extents, 0, Y_AXIS, LEFT); head_ape->offset_ = 0.0; Real padding = robust_scm2double (me->get_property ("padding"), 0.2); - std::vector left_skyline = head_ape->left_skyline_; - heighten_skyline (&left_skyline, - -robust_scm2double (me->get_property ("right-padding"), 0)); + Skyline left_skyline = head_ape->left_skyline_; + left_skyline.raise (-robust_scm2double (me->get_property ("right-padding"), 0)); + /* Add accs entries right-to-left. */ for (vsize i = apes.size (); i-- > 0;) { - Real offset - = -skyline_meshing_distance (apes[i]->right_skyline_, left_skyline); + Real offset = -apes[i]->right_skyline_.distance (left_skyline); if (isinf (offset)) - offset = (i < apes.size () - 1) ? apes[i + 1]->offset_ : 0.0; + offset = (i + 1 < apes.size ()) ? apes[i + 1]->offset_ : 0.0; else offset -= padding; apes[i]->offset_ = offset; - std::vector new_left_skyline = apes[i]->left_skyline_; - heighten_skyline (&new_left_skyline, apes[i]->offset_); - merge_skyline (&new_left_skyline, left_skyline, LEFT); + Skyline new_left_skyline = apes[i]->left_skyline_; + new_left_skyline.raise (apes[i]->offset_); + new_left_skyline.merge (left_skyline); left_skyline = new_left_skyline; } @@ -394,14 +414,14 @@ Accidental_placement::calc_positioning_done (SCM smob) me->flush_extent_cache (X_AXIS); me->set_property ("X-extent", scm_width); - for (vsize i = apes.size (); i--;) - delete apes[i]; + junk_pointers (apes); + delete head_ape; + return SCM_BOOL_T; } ADD_INTERFACE (Accidental_placement, - "accidental-placement-interface", "Resolve accidental collisions.", /* properties */ @@ -409,4 +429,6 @@ ADD_INTERFACE (Accidental_placement, "left-padding " "padding " "positioning-done " - "right-padding ") + "right-padding " + "script-priority " + )