From: Han-Wen Nienhuys Date: Sun, 25 Mar 2007 04:10:53 +0000 (-0300) Subject: make Dot_configuration into class, in new files dot-configuration.{cc,hh} X-Git-Tag: release/2.11.22-1~28^2~11 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=5027fa60c3a76dc406fb1ba8fb4a0e24c2ccf38e;p=lilypond.git make Dot_configuration into class, in new files dot-configuration.{cc,hh} --- diff --git a/lily/dot-column.cc b/lily/dot-column.cc index 3c1eff6c60..6b0ebaeac1 100644 --- a/lily/dot-column.cc +++ b/lily/dot-column.cc @@ -23,6 +23,7 @@ using namespace std; #include "stem.hh" #include "grob.hh" #include "pointer-group-interface.hh" +#include "dot-configuration.hh" /* TODO: let Dot_column communicate with stem via Note_column. @@ -52,162 +53,10 @@ Dot_column::side_position (SCM smob) stem->get_property ("stem-end-position"); } } - + return Side_position_interface::x_aligned_side (smob, SCM_EOL); } -struct Dot_position -{ - int pos_; - Direction dir_; - Grob *dot_; - bool extremal_head_; - - Dot_position () - { - dot_ = 0; - pos_ = 0; - dir_ = CENTER; - extremal_head_ = false; - } -}; - -typedef map Dot_configuration; - -/* - Value CFG according. -*/ -int -dot_config_badness (Dot_configuration const &cfg) -{ - int t = 0; - for (Dot_configuration::const_iterator i (cfg.begin ()); - i != cfg.end (); i++) - { - int p = i->first; - int demerit = sqr (p - i->second.pos_) * 2; - - int dot_move_dir = sign (p - i->second.pos_); - if (i->second.extremal_head_) - { - if (i->second.dir_ - && dot_move_dir != i->second.dir_) - demerit += 3; - else if (dot_move_dir != UP) - demerit += 2; - } - else if (dot_move_dir != UP) - demerit += 1; - - t += demerit; - } - - return t; -} - -void -print_dot_configuration (Dot_configuration const &cfg) -{ - printf ("dotconf { "); - for (Dot_configuration::const_iterator i (cfg.begin ()); - i != cfg.end (); i++) - printf ("%d, ", i->first); - printf ("} \n"); -} - -/* - Shift K and following (preceding) entries up (down) as necessary to - prevent staffline collisions if D is up (down). - - If K is in CFG, then do nothing. -*/ - -Dot_configuration -shift_one (Dot_configuration const &cfg, - int k, Direction d) -{ - Dot_configuration new_cfg; - int offset = 0; - - if (d > 0) - { - for (Dot_configuration::const_iterator i (cfg.begin ()); - i != cfg.end (); i++) - { - int p = i->first; - if (p == k) - { - if (Staff_symbol_referencer::on_line (i->second.dot_, p)) - p += d; - else - p += 2* d; - - offset = 2*d; - - new_cfg[p] = i->second; - } - else - { - if (new_cfg.find (p) == new_cfg.end ()) - offset = 0; - new_cfg[p + offset] = i->second; - } - } - } - else - { - Dot_configuration::const_iterator i (cfg.end ()); - do - { - i--; - - int p = i->first; - if (p == k) - { - if (Staff_symbol_referencer::on_line (i->second.dot_, p)) - p += d; - else - p += 2* d; - - offset = 2*d; - - new_cfg[p] = i->second; - } - else - { - if (new_cfg.find (p) == new_cfg.end ()) - offset = 0; - - new_cfg[p + offset] = i->second; - } - } - while (i != cfg.begin ()); - } - - return new_cfg; -} - -/* - Remove the collision in CFG either by shifting up or down, whichever - is best. -*/ -void -remove_collision (Dot_configuration &cfg, int p) -{ - bool collide = cfg.find (p) != cfg.end (); - - if (collide) - { - Dot_configuration cfg_up = shift_one (cfg, p, UP); - Dot_configuration cfg_down = shift_one (cfg, p, DOWN); - - int b_up = dot_config_badness (cfg_up); - int b_down = dot_config_badness (cfg_down); - - cfg = (b_up < b_down) ? cfg_up : cfg_down; - } -} - MAKE_SCHEME_CALLBACK (Dot_column, calc_positioning_done, 1); SCM Dot_column::calc_positioning_done (SCM smob) @@ -238,7 +87,7 @@ Dot_column::calc_positioning_done (SCM smob) n->relative_coordinate (c, X_AXIS); } } - + vector_sort (dots, position_less); for (vsize i = dots.size (); i--;) if (!dots[i]->is_live ()) @@ -268,10 +117,10 @@ Dot_column::calc_positioning_done (SCM smob) if (dp.extremal_head_) dp.dir_ = to_dir (dp.dot_->get_property ("direction")); - remove_collision (cfg, p); + cfg.remove_collision (p); cfg[p] = dp; if (Staff_symbol_referencer::on_line (dp.dot_, p)) - remove_collision (cfg, p); + cfg.remove_collision (p); } for (Dot_configuration::const_iterator i (cfg.begin ()); diff --git a/lily/dot-configuration.cc b/lily/dot-configuration.cc new file mode 100644 index 0000000000..7676c14dd4 --- /dev/null +++ b/lily/dot-configuration.cc @@ -0,0 +1,143 @@ +/* + dot-implement.cc -- declare Dot_configuration + + Source file of the GNU LilyPond music typesetter. Distributed under + terms of the GNU General Public License. LilyPond comes with NO + WARRANTY. + + (c) 1997--2007 Han-Wen Nienhuys +*/ + +#include "dot-configuration.hh" +#include "staff-symbol-referencer.hh" + + +int +Dot_configuration::badness () const +{ + int t = 0; + for (Dot_configuration::const_iterator i (begin ()); + i != end (); i++) + { + int p = i->first; + int demerit = sqr (p - i->second.pos_) * 2; + + int dot_move_dir = sign (p - i->second.pos_); + if (i->second.extremal_head_) + { + if (i->second.dir_ + && dot_move_dir != i->second.dir_) + demerit += 3; + else if (dot_move_dir != UP) + demerit += 2; + } + else if (dot_move_dir != UP) + demerit += 1; + + t += demerit; + } + + return t; +} + +void +Dot_configuration::print () const +{ + printf ("dotconf { "); + for (Dot_configuration::const_iterator i (begin ()); + i != end (); i++) + printf ("%d, ", i->first); + printf ("} \n"); +} + +/* + Shift K and following (preceding) entries up (down) as necessary to + prevent staffline collisions if D is up (down). + + If K is in CFG, then do nothing. +*/ + +Dot_configuration +Dot_configuration::shifted (int k, Direction d) const +{ + Dot_configuration new_cfg; + int offset = 0; + + if (d > 0) + { + for (Dot_configuration::const_iterator i (begin ()); + i != end (); i++) + { + int p = i->first; + if (p == k) + { + if (Staff_symbol_referencer::on_line (i->second.dot_, p)) + p += d; + else + p += 2* d; + + offset = 2*d; + + new_cfg[p] = i->second; + } + else + { + if (new_cfg.find (p) == new_cfg.end ()) + offset = 0; + new_cfg[p + offset] = i->second; + } + } + } + else + { + Dot_configuration::const_iterator i (end ()); + do + { + i--; + + int p = i->first; + if (p == k) + { + if (Staff_symbol_referencer::on_line (i->second.dot_, p)) + p += d; + else + p += 2* d; + + offset = 2*d; + + new_cfg[p] = i->second; + } + else + { + if (new_cfg.find (p) == new_cfg.end ()) + offset = 0; + + new_cfg[p + offset] = i->second; + } + } + while (i != begin ()); + } + + return new_cfg; +} + +/* + Remove the collision in CFG either by shifting up or down, whichever + is best. +*/ +void +Dot_configuration::remove_collision (int p) +{ + bool collide = find (p) != end (); + + if (collide) + { + Dot_configuration cfg_up = shifted (p, UP); + Dot_configuration cfg_down = shifted (p, DOWN); + + int b_up = cfg_up.badness (); + int b_down = cfg_down.badness (); + + *this = (b_up < b_down) ? cfg_up : cfg_down; + } +} diff --git a/lily/include/dot-configuration.hh b/lily/include/dot-configuration.hh new file mode 100644 index 0000000000..1eed8f3c35 --- /dev/null +++ b/lily/include/dot-configuration.hh @@ -0,0 +1,44 @@ +/* + dot-configuration.hh -- declare Dot_configuration + + Source file of the GNU LilyPond music typesetter. Distributed under + terms of the GNU General Public License. LilyPond comes with NO + WARRANTY. + + (c) 2007 Han-Wen Nienhuys +*/ + +#ifndef DOT_CONFIGURATION_HH +#define DOT_CONFIGURATION_HH + +#include "lily-proto.hh" +#include "direction.hh" + +#include + +struct Dot_position +{ + int pos_; + Direction dir_; + Grob *dot_; + bool extremal_head_; + + Dot_position () + { + dot_ = 0; + pos_ = 0; + dir_ = CENTER; + extremal_head_ = false; + } +}; + +struct Dot_configuration : public map +{ + int badness () const; + void print () const; + Dot_configuration shifted (int k, Direction d) const; + + void remove_collision (int p); +}; + +#endif