From: fred Date: Tue, 26 Mar 2002 23:09:50 +0000 (+0000) Subject: lilypond-1.3.37 X-Git-Tag: release/1.5.59~1736 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=c85a633366c988094b9e6b30f336a6ee0a1bb85c;p=lilypond.git lilypond-1.3.37 --- diff --git a/lily/align-interface.cc b/lily/align-interface.cc new file mode 100644 index 0000000000..6908147504 --- /dev/null +++ b/lily/align-interface.cc @@ -0,0 +1,172 @@ +/* + align-interface.cc -- implement Align_interface + + source file of the GNU LilyPond music typesetter + + (c) 2000 Han-Wen Nienhuys + + */ + +#include "align-interface.hh" +#include "dimension-cache.hh" +#include "score-element.hh" +#include "group-interface.hh" +#include "axis-group-interface.hh" + +/* + This callback is set in the children of the align element. It does + not compute anything, but a side effect of a->do_side_processing () + is that the elements are placed correctly. */ +Real +Align_interface::alignment_callback (Dimension_cache const *c) +{ + Axis ax = c->axis (); + Score_element * sc = c->element_l ()->parent_l (ax); + + if (sc && sc->get_elt_property ("alignment-done") == SCM_UNDEFINED) + { + Align_interface (sc).do_side_processing (ax); + } + return 0.0; +} + +/* + Hairy function to put elements where they should be. Can be tweaked + from the outside by setting minimum-space and extra-space in its + children */ +void +Align_interface::do_side_processing (Axis a) +{ + elt_l_->set_elt_property ("alignment-done", SCM_BOOL_T); + + SCM d = elt_l_->get_elt_property ("stacking-dir"); + Direction stacking_dir = gh_number_p(d) ? to_dir (d) : CENTER; + if (!stacking_dir) + stacking_dir = DOWN; + + + Array dims; + + Link_array elems; + Link_array all_elts + = Group_interface__extract_elements ( elt_l_, (Score_element*) 0, "elements"); + for (int i=0; i < all_elts.size(); i++) + { + Interval y = all_elts[i]->extent(a) + all_elts[i]->relative_coordinate (elt_l_, a); + if (!y.empty_b()) + { + Score_element *e =dynamic_cast(all_elts[i]); + + // todo: fucks up if item both in Halign & Valign. + SCM min_dims = e->remove_elt_property ("minimum-space"); + if (gh_pair_p (min_dims) && + gh_number_p (gh_car (min_dims)) + && gh_number_p (gh_cdr (min_dims))) + { + y.unite (Interval (gh_scm2double (gh_car (min_dims)), + gh_scm2double (gh_cdr (min_dims)))); + } + + SCM extra_dims = e->remove_elt_property ("extra-space"); + if (gh_pair_p (extra_dims) && + gh_number_p (gh_car (extra_dims)) + && gh_number_p (gh_cdr (extra_dims))) + { + y[LEFT] += gh_scm2double (gh_car (extra_dims)); + y[RIGHT] += gh_scm2double (gh_cdr (extra_dims)); + } + + elems.push (e); + dims.push (y); + } + } + + + Interval threshold = Interval (0, Interval::infinity ()); + SCM thr = elt_l_->get_elt_property ("threshold"); + if (gh_pair_p (thr)) + { + threshold[SMALLER] = gh_scm2double (gh_car (thr)); + threshold[BIGGER] = gh_scm2double (gh_cdr (thr)); + } + + Real where_f=0; + for (int i=0 ; i < elems.size(); i++) + { + Real dy = - stacking_dir * dims[i][-stacking_dir]; + if (i) + dy += stacking_dir * dims[i-1][stacking_dir]; + + if (i) + { + dy = (dy >? threshold[SMALLER] ) + translate_axis (where_f, a); + } +} + + +Axis +Align_interface::axis ()const +{ + return Axis (gh_scm2int (gh_car (elt_l_->get_elt_property ("axes")))); +} + + +/* + should use generic Scm funcs. + */ +int +Align_interface::get_count (Score_element*s)const +{ + SCM e = elt_l_->get_elt_property ("elements"); + int c =0; + while (gh_pair_p (e)) + { + if (gh_car (e) == s->self_scm_) + break; + c++; + e = gh_cdr (e); + } + return c; +} + +void +Align_interface::add_element (Score_element* s) +{ + s->add_offset_callback (alignment_callback, axis ()); + Axis_group_interface (elt_l_).add_element (s); + +} + +Align_interface::Align_interface (Score_element const*s) +{ + elt_l_ = (Score_element*)s; +} + +void +Align_interface::set_interface () +{ + Axis_group_interface (elt_l_).set_interface (); + + Group_interface (elt_l_, "interfaces").add_thing (ly_symbol2scm ("Alignment")); +} + +void +Align_interface::set_axis (Axis a) +{ + Axis_group_interface (elt_l_).set_axes (a,a ); +} + +bool +Align_interface::has_interface_b () +{ + SCM memq = scm_memq (ly_symbol2scm ("Alignment"), + elt_l_->get_elt_property ("interfaces")); + + return (memq != SCM_BOOL_F); +} + diff --git a/lily/align-note-column-engraver.cc b/lily/align-note-column-engraver.cc index 5bde41d6bf..a184e36131 100644 --- a/lily/align-note-column-engraver.cc +++ b/lily/align-note-column-engraver.cc @@ -9,6 +9,7 @@ #include "engraver.hh" #include "grace-align-item.hh" +#include "align-interface.hh" #include "note-column.hh" #include "local-key-item.hh" #include "warn.hh" @@ -104,7 +105,7 @@ Align_note_column_engraver::process_acknowledged () if (now_column_l_) { - align_item_p_->add_element (now_column_l_); + Align_interface (align_item_p_).add_element (now_column_l_); now_column_l_ =0; } } diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index d00b7a1cea..f15c84ca5c 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -12,13 +12,12 @@ #include "dimension-cache.hh" Axis_group_interface::Axis_group_interface (Score_element*s) - : Group_interface (s) { elt_l_ = s; } Axis_group_interface -axis_group (Score_element*s) +Axis_group_interface (Score_element*s) { return Axis_group_interface (s); } @@ -37,7 +36,7 @@ Axis_group_interface::add_element (Score_element *e) e->set_parent (elt_l_, a); } - Group_interface::add_element (e); + Group_interface (elt_l_).add_element (e); elt_l_->add_dependency (e); } @@ -116,7 +115,7 @@ Axis_group_interface::get_children () { Score_element* e = unsmob_element (gh_car (ep)); if (e) - childs.concat (axis_group (e).get_children ()); + childs.concat (Axis_group_interface (e).get_children ()); } return childs; diff --git a/lily/break-align-engraver.cc b/lily/break-align-engraver.cc index 82f6dd904d..ec8495d9ba 100644 --- a/lily/break-align-engraver.cc +++ b/lily/break-align-engraver.cc @@ -9,7 +9,7 @@ #include "engraver.hh" #include "protected-scm.hh" #include "break-align-item.hh" -#include "axis-group-item.hh" +#include "align-interface.hh" #include "axis-group-interface.hh" class Break_align_engraver : public Engraver @@ -34,7 +34,7 @@ void Break_align_engraver::add_column (SCM smob) { Score_element * e = unsmob_element (smob); - align_l_->add_element (e); + Align_interface (align_l_).add_element (e); typeset_element (e); } @@ -103,21 +103,25 @@ Break_align_engraver::acknowledge_element (Score_element_info inf) SCM name = ly_str02scm (inf.elem_l_->name()); SCM s = scm_assoc (name, column_alist_); - Axis_group_item * group = 0; + Item * group = 0; + if (s != SCM_BOOL_F) { Score_element *e = unsmob_element (gh_cdr(s)); - group = dynamic_cast (e); + group = dynamic_cast (e); } else { - group = new Axis_group_item; - axis_group(group).set_axes (X_AXIS,X_AXIS); + group = new Item; + + Axis_group_interface (group).set_interface (); + Axis_group_interface (group).set_axes (X_AXIS,X_AXIS); + group->set_elt_property ("origin", name); group->set_parent (align_l_, Y_AXIS); announce_element (Score_element_info (group, 0)); column_alist_ = scm_assoc_set_x (column_alist_, name, group->self_scm_); } - axis_group (group).add_element (item_l); + Axis_group_interface (group).add_element (item_l); } } diff --git a/lily/break-align-item.cc b/lily/break-align-item.cc index c0c2ac4807..ebaf7f3aee 100644 --- a/lily/break-align-item.cc +++ b/lily/break-align-item.cc @@ -17,12 +17,7 @@ #include "paper-def.hh" #include "paper-column.hh" #include "group-interface.hh" - -/* - Handle spacing for prefatory matter. - - TODO: rewrite this. It is kludgy -*/ +#include "align-interface.hh" void Break_align_item::before_line_breaking () @@ -40,7 +35,7 @@ Break_align_item::before_line_breaking () for (int i=0; i < all_elems.size(); i++) { - Interval y = all_elems[i]->extent(axis ()); + Interval y = all_elems[i]->extent(X_AXIS); if (!y.empty_b()) elems.push (dynamic_cast (all_elems[i])); } @@ -105,10 +100,12 @@ Break_align_item::before_line_breaking () scm_set_car_x (first_pair, gh_double2scm (-dists[0])); elems[0]->set_elt_property ("minimum-space", first_pair); - - Axis_align_item::before_line_breaking (); + /* + Force callbacks for alignment to be called + */ + Real unused = elems[0]->relative_coordinate (this, X_AXIS); Real pre_space = elems[0]->relative_coordinate (column_l (), X_AXIS); Real xl = elems[0]->extent (X_AXIS)[LEFT]; @@ -156,7 +153,9 @@ Break_align_item::before_line_breaking () Break_align_item::Break_align_item () { set_elt_property ("stacking-dir" , gh_int2scm (RIGHT)); - set_axis (X_AXIS); + + Align_interface (this).set_interface (); + Align_interface (this).set_axis (X_AXIS); add_offset_callback (Side_position_interface::aligned_on_self, X_AXIS); } diff --git a/lily/cross-staff.cc b/lily/cross-staff.cc index c7855b5836..e187466121 100644 --- a/lily/cross-staff.cc +++ b/lily/cross-staff.cc @@ -1,6 +1,6 @@ #include "cross-staff.hh" #include "item.hh" -#include "align-element.hh" +#include "align-interface.hh" #include "spanner.hh" #include "warn.hh" @@ -9,10 +9,11 @@ calc_interstaff_dist (Item const *item, Spanner const *span) { Real interstaff = 0.0; Score_element *common = item->common_refpoint (span, Y_AXIS); - Align_element * align = dynamic_cast (common); - if (align && align->axis() == Y_AXIS) + Align_interface align(common); + + if (align.has_interface_b () && align.axis() == Y_AXIS) { - SCM threshold = align->get_elt_property ("threshold"); + SCM threshold = common->get_elt_property ("threshold"); if (!gh_pair_p (threshold) || !scm_equal_p (gh_car (threshold), gh_cdr (threshold))) warning (_ ("minVerticalAlign != maxVerticalAlign: cross staff spanners may be broken")); @@ -30,9 +31,9 @@ calc_interstaff_dist (Item const *item, Spanner const *span) note_refpoint = note_refpoint->parent_l (Y_AXIS); int span_prio = - align->get_count ((Score_element*) dynamic_cast (span_refpoint)); + align.get_count ((Score_element*) dynamic_cast (span_refpoint)); int item_prio = - align->get_count ((Score_element*) dynamic_cast (note_refpoint)); + align.get_count ((Score_element*) dynamic_cast (note_refpoint)); /* our staff is lower -> interstaff *= -1 diff --git a/lily/grace-position-engraver.cc b/lily/grace-position-engraver.cc index 735ba6b69a..3805612e1c 100644 --- a/lily/grace-position-engraver.cc +++ b/lily/grace-position-engraver.cc @@ -93,7 +93,7 @@ Grace_position_engraver::do_pre_move_processing () warning (_("Unattached grace notes. Attaching to last musical column.")); align_l_->set_parent (0, X_AXIS); - axis_group(last_musical_col_l_).add_element (align_l_); + Axis_group_interface (last_musical_col_l_).add_element (align_l_); } last_musical_col_l_ = get_staff_info ().musical_pcol_l (); diff --git a/lily/include/align-interface.hh b/lily/include/align-interface.hh new file mode 100644 index 0000000000..0809620234 --- /dev/null +++ b/lily/include/align-interface.hh @@ -0,0 +1,52 @@ +/* + align-interface.hh -- declare Align_interface + + source file of the GNU LilyPond music typesetter + + (c) 2000 Han-Wen Nienhuys + + */ + +#ifndef ALIGN_INTERFACE_HH +#define ALIGN_INTERFACE_HH + +#include "axes.hh" +#include "lily-proto.hh" + +/* + TODO: rewrite this comment. + + + Order elements top to bottom/left to right/right to left etc.. + + TODO: implement padding. + + document usage of this. + + + + ******* + + element properties + + stacking-dir + + Which side to align? -1: left side, 0: centered (around + center_l_ if not nil, or around center of width), 1: right side + */ +struct Align_interface { + Score_element * elt_l_; + + Align_interface (Score_element const*); + static Real alignment_callback (Dimension_cache const *); + void do_side_processing (Axis a); + void set_axis (Axis); + Axis axis () const; + void add_element (Score_element*); + int get_count (Score_element*)const; + void set_interface (); + bool has_interface_b (); +}; + +#endif /* ALIGN_INTERFACE_HH */ + diff --git a/lily/include/axis-group-interface.hh b/lily/include/axis-group-interface.hh index 9ceee2fcb1..f1382da9be 100644 --- a/lily/include/axis-group-interface.hh +++ b/lily/include/axis-group-interface.hh @@ -12,10 +12,27 @@ #include "group-interface.hh" -struct Axis_group_interface : Group_interface +/** + Treat a group of elements as a union. This sets the parent of any S + added to ELT_L_ to ELT_L_. + + Properties: + + axes -- list of axis (number) in which this group works + + transparent -- an Axis_group is transparent by default + + elements -- contains list of pointers to other elements + + interfaces -- Axis_group is added to this list. +*/ +struct Axis_group_interface { + Score_element *elt_l_; Axis_group_interface (Score_element*); + static Interval group_extent_callback (Dimension_cache const*); + void add_element (Score_element*); void set_axes (Axis,Axis); bool axis_b (Axis)const; @@ -24,8 +41,5 @@ struct Axis_group_interface : Group_interface void set_interface (); }; -Axis_group_interface -axis_group (Score_element*); - #endif /* AXIS_GROUP_INTERFACE_HH */ diff --git a/lily/include/context-specced-music.hh b/lily/include/context-specced-music.hh index 56206a3bdf..abcf2c40f3 100644 --- a/lily/include/context-specced-music.hh +++ b/lily/include/context-specced-music.hh @@ -15,11 +15,7 @@ class Context_specced_music : public Music_wrapper { public: - /** The kind of translation needed for this music. This doesn't - make sense for simple (ie non-list) music, but it does no harm - here. Yes, it did harm Music_sequence: you can forget to copy it. - - */ + /// The kind of translation needed for this music. String translator_type_str_; /// what identification for the translation unit diff --git a/lily/include/grace-align-item.hh b/lily/include/grace-align-item.hh index f3bb2af3c4..ed16719bca 100644 --- a/lily/include/grace-align-item.hh +++ b/lily/include/grace-align-item.hh @@ -11,9 +11,9 @@ #define GRACE_ALIGN_ITEM_HH -#include "axis-align-item.hh" +#include "item.hh" -class Grace_align_item : public Axis_align_item +class Grace_align_item : public Item { public: VIRTUAL_COPY_CONS (Score_element); diff --git a/lily/include/group-interface.hh b/lily/include/group-interface.hh index 509fcdf25b..72bc892258 100644 --- a/lily/include/group-interface.hh +++ b/lily/include/group-interface.hh @@ -15,15 +15,14 @@ #include "lily-guile.hh" #include "smobs.hh" -/* - rename to list interface? - */ - /** Look at Score element ELT as thing which has a list property called NAME_. Normally the list would contain Score_elements, but sometimes it can be different things. + + todo: reename as list_interface? */ + struct Group_interface { Score_element * elt_l_; diff --git a/lily/include/score-element.hh b/lily/include/score-element.hh index 9bcbd2e33c..8fde243cd8 100644 --- a/lily/include/score-element.hh +++ b/lily/include/score-element.hh @@ -17,24 +17,24 @@ typedef void (Score_element::*Score_element_method_pointer) (void); -/** Both Spanner and Item are Score_element's. Most Score_element's depend - on other Score_element's, eg, Beam needs to know and set direction of - Stem. So the Beam has to be calculated *before* Stem. This is - accomplished with the dependencies fields of struct Score_element, - which are implemented in the Directed_graph_node class: all elements - form an acyclic graph. +/** + Basic output object. - (elem) + Element Properties: + transparent -- boolean: if true, do not print anything black. -Element Properties: + dependencies -- list of score-element pointers that indicate who to + compute first. -Boolean (true iff defined) + interfaces -- list of symbols indicating the interfaces supported + by this object. - break_helper_only -- if defined try to junk this after calcing breakpoints. - - transparent -- do not calc. output + extra-offset -- pair of reals (a cons) forcing an extra offset + before outputting + glyph -- afm character name to output. + */ class Score_element { /** @@ -170,6 +170,8 @@ public: /** Set this if anyone points to me, or if I point to anyone. + + JUNKME. */ bool used_b_; diff --git a/lily/include/side-position-interface.hh b/lily/include/side-position-interface.hh index 12495db3af..839c088c2c 100644 --- a/lily/include/side-position-interface.hh +++ b/lily/include/side-position-interface.hh @@ -13,6 +13,27 @@ #include "spanner.hh" #include "item.hh" + +/** + Position victim object (ELT_L_) next to other objects (the support). + + side-support -- list of score elements + + direction -- where to put the victim object (left or right?) + + side-relative-direction -- if set: get the direction from a different object, and multiply by this. + + direction-source -- in case side-relative-direction is set, where + to get the direction + + minimum-space -- minimum distance that the victim should move + (after padding) + + padding -- add this much extra space between victim and support + + TODO: move out unrelated callbacks. + + */ struct Side_position_interface { Score_element * elt_l_; diff --git a/lily/include/span-bar.hh b/lily/include/span-bar.hh index bc93e8fe3d..93213fa0b2 100644 --- a/lily/include/span-bar.hh +++ b/lily/include/span-bar.hh @@ -29,7 +29,6 @@ public: VIRTUAL_COPY_CONS(Score_element); void add_bar (Score_element*); - void set_align (Align_element *); protected: void evaluate_empty (); diff --git a/lily/item.cc b/lily/item.cc index d9abade41b..45cea7a7c4 100644 --- a/lily/item.cc +++ b/lily/item.cc @@ -19,6 +19,17 @@ Item::Item () broken_to_drul_[LEFT] = broken_to_drul_[RIGHT]=0; } +/** + Item copy ctor. Copy nothing: everything should be a elt property + or a special purpose poitner (such as broken_to_drul_[]) */ +Item::Item (Item const &s) + : Score_element (s) +{ + broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0; +} + + + bool Item::breakable_b () const { @@ -29,12 +40,6 @@ Item::breakable_b () const return (i) ? i->breakable_b () : to_boolean (get_elt_property( "breakable")); } -Real -Item::hpos_f() const -{ - return relative_coordinate (0, X_AXIS); -} - Line_of_score * Item::line_l() const { @@ -163,12 +168,6 @@ Item::column_l () const return dynamic_cast (parent_l (X_AXIS))->column_l (); } -Item::Item (Item const &s) - : Score_element (s) -{ - broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0; -} - Direction Item::break_status_dir () const { diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index 15d490bca6..bb6f642427 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -152,7 +152,7 @@ Score_engraver::typeset_all() } } if (!elem_p->parent_l(Y_AXIS)) - axis_group (scoreline_l_).add_element (elem_p); + Axis_group_interface (scoreline_l_).add_element (elem_p); } elem_p_arr_.clear(); } diff --git a/lily/slur.cc b/lily/slur.cc index b5ce992237..7a0f91f941 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -320,12 +320,12 @@ Slur::encompass_offset (Note_column const* col) const if (!stem_l) { warning (_ ("Slur over rest?")); - o[X_AXIS] = col->hpos_f (); + o[X_AXIS] = col->relative_coordinate (0, X_AXIS); o[Y_AXIS] = col->extent (Y_AXIS)[dir]; return o; } Direction stem_dir = directional_element (stem_l).get (); - o[X_AXIS] = stem_l->hpos_f (); + o[X_AXIS] = stem_l->relative_coordinate (0, X_AXIS); /* Simply set x to middle of notehead @@ -444,7 +444,7 @@ Slur::set_extremities () */ else { - dx_f_drul_[d] = stem_l->hpos_f () + dx_f_drul_[d] = stem_l->relative_coordinate (0, X_AXIS) - get_bound (d)->relative_coordinate (0, X_AXIS); /* side attached to beamed stem diff --git a/lily/span-bar.cc b/lily/span-bar.cc index 7ed3c4a6c7..d16081928e 100644 --- a/lily/span-bar.cc +++ b/lily/span-bar.cc @@ -11,7 +11,6 @@ #include "dimensions.hh" #include "paper-def.hh" #include "molecule.hh" -#include "align-element.hh" #include "warn.hh" #include "group-interface.hh" diff --git a/lily/stem-tremolo.cc b/lily/stem-tremolo.cc index d945dc2463..855aa46d03 100644 --- a/lily/stem-tremolo.cc +++ b/lily/stem-tremolo.cc @@ -60,8 +60,8 @@ Stem_tremolo::do_brew_molecule () const SCM s = beam->get_elt_property ("height"); if (gh_number_p (s)) dy = gh_scm2double (s); - Real dx = beam->last_visible_stem ()->hpos_f () - - beam->first_visible_stem ()->hpos_f (); + Real dx = beam->last_visible_stem ()->relative_coordinate (0, X_AXIS) + - beam->first_visible_stem ()->relative_coordinate (0, X_AXIS); dydx = dx ? dy/dx : 0; } else @@ -99,7 +99,7 @@ Stem_tremolo::do_brew_molecule () const { // ugh, rather calc from Stem_tremolo_req int beams_i = stem->beam_count(RIGHT) >? stem->beam_count (LEFT); - mol.translate (Offset(stem->hpos_f () - hpos_f (), + mol.translate (Offset(stem->relative_coordinate (0, X_AXIS) - relative_coordinate (0, X_AXIS), stem->stem_end_position () * half_space - directional_element (beam).get () * beams_i * interbeam_f)); } @@ -121,7 +121,7 @@ Stem_tremolo::do_brew_molecule () const else whole_note_correction = 0; - mol.translate (Offset (stem->hpos_f () - hpos_f () + + mol.translate (Offset (stem->relative_coordinate (0, X_AXIS) - relative_coordinate (0, X_AXIS) + whole_note_correction, dy)); } diff --git a/lily/tuplet-spanner.cc b/lily/tuplet-spanner.cc index ab38ee1514..1669899c18 100644 --- a/lily/tuplet-spanner.cc +++ b/lily/tuplet-spanner.cc @@ -157,15 +157,15 @@ Tuplet_spanner::calc_position_and_height (Real *offset, Real * dy) const *offset = - d * infinity_f; - Real x0 = column_arr[0]->hpos_f (); - Real x1 = column_arr.top ()->hpos_f (); + Real x0 = column_arr[0]->relative_coordinate (0, X_AXIS); + Real x1 = column_arr.top ()->relative_coordinate (0, X_AXIS); Real factor = column_arr.size () > 1 ? 1/(x1 - x0) : 1.0; for (int i = 0; i < column_arr.size (); i++) { Real notey = column_arr[i]->extent (Y_AXIS)[d]; - Real x = column_arr[i]->hpos_f () - x0; + Real x = column_arr[i]->relative_coordinate (0, X_AXIS) - x0; Real tuplety = *dy * x * factor; if (notey * d > (*offset + tuplety) * d)