$(tree-share-prefix)/mf-link-tree link-mf-tree: $(tree-share-prefix)/lilypond-force
-rm -f $(tree-share-prefix)/fonts/otf/* && \
rm -f $(tree-share-prefix)/fonts/svg/* && \
+ rm -f $(tree-share-prefix)/fonts/fonts.conf && \
rm -f $(tree-share-prefix)/fonts/tfm/* && \
rm -f $(tree-share-prefix)/fonts/type1/* && \
cd $(tree-share-prefix)/fonts/otf && \
ln -s ../../../../../../mf/$(outconfbase)/*.otf .
+ -cd $(tree-share-prefix)/fonts/ && \
+ ln -s ../../../../../mf/$(outconfbase)/fonts.conf .
-cd $(tree-share-prefix)/fonts/svg && \
ln -s ../../../../../../mf/$(outconfbase)/*.svg .
-cd $(tree-share-prefix)/fonts/tfm && \
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=11
-PATCH_LEVEL=20
+PATCH_LEVEL=21
MY_PATCH_LEVEL=
return *this;
}
Offset direction () const;
+ Offset swapped () const;
Real arg () const;
Real angle_degrees () const;
d /= length ();
return d;
}
+
+Offset
+Offset::swapped () const
+{
+ return Offset (coordinate_a_[Y_AXIS], coordinate_a_[X_AXIS]);
+}
#(ly:set-option 'backend 'eps)
%% TODO: what to do if inkscape fails?
-#(display "Invoking inkscape...\n")
+#(ly:progress "Invoking inkscape...\n")
+
+%% LD_LIBRARY_PATH is necesssary, otherwise, it doesn't build in GUB.
+%% LD_LIBRARY_PATH is part of the start-environment but should be switched off
+%% for external inkscape.
+#(ly:system (format #f "LD_LIBRARY_PATH= inkscape -T -E ~a-inkscape.eps ~a-1.svg" outname outname)
+ (cons
+ (format #f "FONTCONFIG_FILE=~a/fonts/fonts.conf" (ly:effective-prefix))
+ (ly:start-environment)))
-%% LD_LIBRARY_PATH is necesssary, otherwise, it doesn't build in GUB.
-#(system (format #f "LD_LIBRARY_PATH= inkscape -T -E ~a-1.eps ~a-1.svg" outname outname))
#(set! output-count 0)
#(set-default-paper-size "a5")
\score {
\lyrics {
\markup {
- \epsfile #X #30.0 #(format #f "~a-1.eps" outname)
+ \epsfile #X #30.0 #(format #f "~a-inkscape.eps" outname)
}
- x x x
+ bla bla bla
}
}
}
-
-
-
\header { texidoc = "Collision resolution tries to put notes with dots
on the right side."
}
--- /dev/null
+\header {
+
+ texidoc = "in collisions, the stems of outer voice are added to the
+ dot support of the inner voices."
+
+}
+
+\version "2.11.21"
+
+\layout { ragged-right = ##t }
+
+\new Staff {
+ \key e \major \time 3/4
+ \relative c'' {
+ << { dis4. } \\
+ { fis,4 } \\ { b4 } >>
+ }
+}
--- /dev/null
+\header {
+
+ texidoc = "Scripts on chords with seconds remain centered on the extremal note head"
+ }
+
+
+\version "2.10.21"
+\layout { ragged-right = ##t }
+
+\relative c''{
+ <g a>-.
+ <g a>_.
+}
#include <cstdio>
#include <cmath>
#include <map>
+#include <set>
+
using namespace std;
#include "dots.hh"
#include "stem.hh"
#include "grob.hh"
#include "pointer-group-interface.hh"
+#include "dot-configuration.hh"
+#include "note-head.hh"
+#include "rest.hh"
+#include "dot-formatting-problem.hh"
-/*
- TODO: let Dot_column communicate with stem via Note_column.
-*/
-
-MAKE_SCHEME_CALLBACK (Dot_column, side_position, 1);
+MAKE_SCHEME_CALLBACK (Dot_column, calc_positioning_done, 1);
SCM
-Dot_column::side_position (SCM smob)
-{
- Grob *me = unsmob_grob (smob);
- extract_grob_set (me, "dots", dots);
-
- for (vsize i = 0; i < dots.size (); i++)
- {
- Grob *head = dots[i]->get_parent (Y_AXIS);
- Grob *stem = head ? unsmob_grob (head->get_object ("stem")) : 0;
- if (stem
- && !Stem::get_beam (stem)
- && Stem::duration_log (stem) > 2
- && !Stem::is_invisible (stem))
- {
- /*
- trigger stem end & direction calculation.
-
- This will add the stem to the support if a flag collision happens.
- */
- stem->get_property ("stem-end-position");
- }
- }
-
- return Side_position_interface::x_aligned_side (smob, SCM_EOL);
-}
-
-struct Dot_position
+Dot_column::calc_positioning_done (SCM smob)
{
- int pos_;
- Direction dir_;
- Grob *dot_;
- bool extremal_head_;
-
- Dot_position ()
- {
- dot_ = 0;
- pos_ = 0;
- dir_ = CENTER;
- extremal_head_ = false;
- }
-};
+ Grob *me = unsmob_grob (smob);
-typedef map<int, Dot_position> Dot_configuration;
+ me->set_property ("positioning-done", SCM_BOOL_T);
-/*
- 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;
+ vector<Grob*> dots
+ = extract_grob_array (me, "dots");
- 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;
+ vector<Grob*> main_heads;
+ Real ss = 0;
- t += demerit;
- }
+ Grob *commonx = me;
+ { /*
+ Trigger note collision resolution first, since that may kill off
+ dots when merging.
+ */
+ for (vsize i = 0; i < dots.size (); i++)
+ {
+ Grob *n = dots[i]->get_parent (Y_AXIS);
+ commonx = n->common_refpoint (commonx, X_AXIS);
- return t;
-}
+ if (Grob *stem = unsmob_grob (n->get_object("stem")))
+ {
+ commonx = stem->common_refpoint (commonx, X_AXIS);
-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");
-}
+ if (Stem::first_head (stem) == n)
+ main_heads.push_back (n);
+ }
+ }
+ }
-/*
- Shift K and following (preceding) entries up (down) as necessary to
- prevent staffline collisions if D is up (down).
+ vector<Box> boxes;
+ set<Grob*> stems;
- If K is in CFG, then do nothing.
-*/
+ extract_grob_set(me, "side-support-elements", support);
-Dot_configuration
-shift_one (Dot_configuration const &cfg,
- int k, Direction d)
-{
- Dot_configuration new_cfg;
- int offset = 0;
-
- if (d > 0)
+ Interval base_x;
+ for (vsize i = 0; i < main_heads.size (); i++)
+ base_x.unite (main_heads[i]->extent (commonx, X_AXIS));
+
+ for (vsize i = 0; i < support.size (); i++)
{
- for (Dot_configuration::const_iterator i (cfg.begin ());
- i != cfg.end (); i++)
+ Grob *s = support[i];
+ if (!ss)
+ ss = Staff_symbol_referencer::staff_space (s);
+
+ /* can't inspect Y extent of rest.
+
+ Rest collisions should wait after line breaking.
+ */
+ Interval y;
+ if (Rest::has_interface (s))
{
- 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;
- }
+ base_x.unite (s->extent (commonx, X_AXIS));
+ continue;
}
- }
- else
- {
- Dot_configuration::const_iterator i (cfg.end ());
- do
+ else if (Stem::has_interface (s))
{
- 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;
- }
+ Real y1 = Stem::head_positions (s)[-get_grob_direction (s)];
+ Real y2 = y1 + get_grob_direction (s) * 7;
+
+ y.add_point (y1);
+ y.add_point (y2);
}
- while (i != cfg.begin ());
- }
+ else
+ y = s->extent (s, Y_AXIS);
- return new_cfg;
-}
+ y *= 2 / ss;
+ y += Staff_symbol_referencer::get_position (s);
+
+ Box b (s->extent (commonx, X_AXIS), y);
+ boxes.push_back (b);
-/*
- 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 (Grob *stem = unsmob_grob (s->get_object ("stem")))
+ stems.insert (stem);
+ }
- if (collide)
+ for (set<Grob*>::const_iterator i(stems.begin());
+ i != stems.end (); i++)
{
- 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;
+ Grob *stem = (*i);
+ Stencil flag = Stem::flag (stem);
+ if (!flag.is_empty ())
+ {
+ Interval y = flag.extent (Y_AXIS)
+ * (2 / ss)
+ + Stem::stem_end_position (stem);
+
+ Interval x = stem->relative_coordinate (commonx, X_AXIS)
+ + flag.extent (X_AXIS);
+
+ boxes.push_back (Box (x,y));
+ }
}
-}
-
-MAKE_SCHEME_CALLBACK (Dot_column, calc_positioning_done, 1);
-SCM
-Dot_column::calc_positioning_done (SCM smob)
-{
- Grob *me = unsmob_grob (smob);
-
- me->set_property ("positioning-done", SCM_BOOL_T);
-
- vector<Grob*> dots
- = extract_grob_array (me, "dots");
-
- { /*
- Trigger note collision resolution first, since that may kill off
- dots when merging.
- */
- Grob *c = 0;
- for (vsize i = dots.size (); i--;)
- {
- Grob *n = dots[i]->get_parent (Y_AXIS);
- if (c)
- c = n->common_refpoint (c, X_AXIS);
- else
- c = n;
- }
- for (vsize i = dots.size (); i--;)
- {
- Grob *n = dots[i]->get_parent (Y_AXIS);
- n->relative_coordinate (c, X_AXIS);
- }
- }
-
+
vector_sort (dots, position_less);
for (vsize i = dots.size (); i--;)
if (!dots[i]->is_live ())
dots.erase (dots.begin () + i);
- Dot_configuration cfg;
- for (vsize i = 0;i < dots.size (); i++)
+ Dot_formatting_problem problem (boxes, base_x);
+
+ Dot_configuration cfg (problem);
+ for (vsize i = 0; i < dots.size (); i++)
{
Dot_position dp;
dp.dot_ = dots[i];
Grob *stem = unsmob_grob (note->get_object ("stem"));
if (stem)
dp.extremal_head_ = Stem::first_head (stem) == note;
+
+ dp.x_extent_ = note->extent (commonx, X_AXIS);
}
int p = Staff_symbol_referencer::get_rounded_position (dp.dot_);
offset callback but adding a dot overwrites Y-offset. */
p += (int) robust_scm2double (dp.dot_->get_property ("staff-position"), 0.0);
dp.pos_ = p;
-
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);
}
+ problem.register_configuration (cfg);
+
for (Dot_configuration::const_iterator i (cfg.begin ());
i != cfg.end (); i++)
{
*/
Staff_symbol_referencer::set_position (i->second.dot_, i->first);
}
+
+
+ me->translate_axis (cfg.x_offset () - me->relative_coordinate (commonx, X_AXIS),
+ X_AXIS);
return SCM_BOOL_T;
}
Pointer_group_interface::add_grob (me, ly_symbol2scm ("dots"), d);
d->set_property ("Y-offset", Grob::x_parent_positioning_proc);
+ d->set_property ("X-offset", Grob::x_parent_positioning_proc);
Axis_group_interface::add_element (me, d);
}
}
ADD_INTERFACE (Dot_column,
"Groups dot objects so they form a column, and position dots so they do not "
- "clash with staff lines ",
+ "clash with staff lines. ",
/* properties */
"dots "
--- /dev/null
+/*
+ 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 <hanwen@xs4all.nl>
+*/
+
+#include "dot-configuration.hh"
+#include "dot-formatting-problem.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 (*problem_);
+ 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;
+ }
+}
+
+Dot_configuration::Dot_configuration (Dot_formatting_problem const &problem)
+{
+ problem_ = &problem;
+}
+
+Real
+Dot_configuration::x_offset () const
+{
+ Real off = 0.0;
+ for (Dot_configuration::const_iterator i (begin ());
+ i != end (); i++)
+ off = max (off, problem_->head_skyline_.height ((*i).first));
+
+ return off;
+}
--- /dev/null
+
+#include "dot-formatting-problem.hh"
+#include "dot-configuration.hh"
+#include "skyline.hh"
+
+Dot_formatting_problem::~Dot_formatting_problem()
+{
+ delete best_;
+}
+
+void
+Dot_formatting_problem::register_configuration (Dot_configuration const &src)
+{
+ int b = src.badness ();
+ if (b < score_)
+ {
+ delete best_;
+ best_ = new Dot_configuration (src);
+ }
+}
+
+Dot_configuration *
+Dot_formatting_problem::best () const
+{
+ return best_;
+}
+
+
+
+Dot_formatting_problem::Dot_formatting_problem (vector<Box> const &boxes, Interval base_x)
+ : head_skyline_ (boxes, 0.0, Y_AXIS, RIGHT)
+{
+ best_ = 0;
+ head_skyline_.set_minimum_height (base_x[RIGHT]);
+}
#include "file-name.hh"
#include "string-convert.hh"
+LY_DEFINE (ly_start_environment, "ly:start-environment",
+ 0, 0, 0, (),
+ "Return the environment, a list of strings, that was in effect at program start")
+{
+ SCM l = SCM_EOL;
+ SCM *tail = &l;
+
+ for (vsize i = 0; i < start_environment_global.size (); i++)
+ {
+ *tail = scm_cons (ly_string2scm (start_environment_global[i]),
+ SCM_EOL);
+ tail = SCM_CDRLOC(*tail);
+ }
+
+ return l;
+}
+
+
LY_DEFINE (ly_find_file, "ly:find-file",
1, 0, 0, (SCM name),
"Return the absolute file name of @var{name}, "
cache_callback = cb;
return SCM_UNSPECIFIED;
}
+#endif
void
Grob::instrumented_set_property (SCM sym, SCM v,
int line,
char const *fun)
{
+#ifndef NDEBUG
if (ly_is_procedure (modification_callback))
scm_apply_0 (modification_callback,
scm_list_n (self_scm (),
scm_from_int (line),
scm_from_locale_string (fun),
sym, v, SCM_UNDEFINED));
+#endif
+
internal_set_property (sym, v);
}
-#endif
SCM
Grob::get_property_alist_chain (SCM def) const
--- /dev/null
+/*
+ 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 <hanwen@xs4all.nl>
+*/
+
+#ifndef DOT_CONFIGURATION_HH
+#define DOT_CONFIGURATION_HH
+
+#include "lily-proto.hh"
+#include "direction.hh"
+#include "box.hh"
+
+#include <map>
+
+struct Dot_position
+{
+ int pos_;
+ Direction dir_;
+ Grob *dot_;
+ Box dot_extents_;
+ bool extremal_head_;
+ Interval x_extent_;
+
+ Dot_position ()
+ {
+ dot_ = 0;
+ pos_ = 0;
+ dir_ = CENTER;
+ extremal_head_ = false;
+ }
+};
+
+struct Dot_configuration : public map<int, Dot_position>
+{
+ Dot_formatting_problem const *problem_;
+
+ Dot_configuration (Dot_formatting_problem const &);
+ Real x_offset () const;
+ int badness () const;
+ void print () const;
+ Dot_configuration shifted (int k, Direction d) const;
+ void remove_collision (int p);
+};
+
+#endif
--- /dev/null
+#ifndef DOT_FORMATTING_PROBLEM_HH
+#define DOT_FORMATTING_PROBLEM_HH
+
+
+#include "skyline.hh"
+#include "std-vector.hh"
+
+#include <map>
+
+struct Dot_formatting_problem
+{
+ Skyline head_skyline_;
+ Dot_configuration *best_;
+ int score_;
+
+ void register_configuration (Dot_configuration const &);
+ Dot_configuration *best () const;
+ Dot_formatting_problem (vector<Box> const &boxes, Interval base_x);
+ ~Dot_formatting_problem();
+};
+
+#endif
class Context_def;
class Context_specced_music;
class Dispatcher;
+class Dot_column;
+class Dot_configuration;
+class Dot_formatting_problem;
class Engraver;
class Engraver;
class Engraver_group;
class Simple_spacer_wrapper;
class Simultaneous_music;
class Simultaneous_music_iterator;
+class Skyline;
class Skyline_entry;
class Slur_configuration;
class Slur_score_state;
/* options */
extern vector<string> dump_header_fieldnames_global;
+extern vector<string> start_environment_global;
extern string output_backend_global;
extern string output_name_global;
extern bool be_safe_global;
static void set_dotcol (Grob *me, Grob *);
static void add_head (Grob *me, Grob *);
static bool has_rests (Grob *me);
+ static Grob *dot_column (Grob *me);
DECLARE_GROB_INTERFACE();
static Item *get_stem (Grob *);
#include "stencil.hh"
#include "grob-interface.hh"
-/** ball at the end of the stem. Also takes care of ledger lines.
-
-NoteHead is a kind of RhythmicHead, see there.
-
-Read-only:
-*/
class Note_head
{
DECLARE_SCHEME_CALLBACK (stem_x_shift, (SCM));
DECLARE_SCHEME_CALLBACK (calc_stem_attachment, (SCM));
DECLARE_GROB_INTERFACE();
+
static Real stem_attachment_coordinate (Grob *, Axis a);
static int get_balltype (Grob *);
DECLARE_GROB_INTERFACE();
DECLARE_SCHEME_CALLBACK (print, (SCM));
DECLARE_SCHEME_CALLBACK (calc_direction, (SCM));
+ DECLARE_SCHEME_CALLBACK (calc_positioning_done, (SCM));
DECLARE_SCHEME_CALLBACK (calc_cross_staff, (SCM));
};
#ifndef SKYLINE_HH
#define SKYLINE_HH
-#include <list>
-
+#include "lily-proto.hh"
#include "axis.hh"
#include "box.hh"
#include "interval.hh"
#include "std-vector.hh"
#include "smobs.hh"
+#include <list>
+
struct Building
{
Real end_;
list<Building> internal_build_skyline (list<Box>*, Real, Axis, Direction);
DECLARE_SIMPLE_SMOBS(Skyline);
+
public:
Skyline ();
Skyline (Skyline const &src);
Skyline (Direction sky);
Skyline (vector<Box> const &bldgs, Real horizon_padding, Axis a, Direction sky);
Skyline (Box const &b, Real horizon_padding, Axis a, Direction sky);
+
vector<Offset> to_points (Axis) const;
void merge (Skyline const &);
void insert (Box const &, Real horizon_padding, Axis);
void print () const;
+ void print_points () const;
void raise (Real);
void shift (Real);
Real distance (Skyline const &) const;
"104857600", overwrite);
}
+vector<string> start_environment_global;
+
int
-main (int argc, char **argv)
+main (int argc, char **argv, char **envp)
{
+ for (char **p = envp; *p; p++)
+ start_environment_global.push_back(*p);
+
if (getenv ("LILYPOND_VERBOSE"))
be_verbose_global = true;
far to the right.
*/
if (Dot_column::has_interface (parent))
- Side_position_interface::add_support (parent, nu);
+ {
+ Grob *stem = unsmob_grob (nu->get_object ("stem"));
+ extract_grob_set (stem, "note-heads", heads);
+ for (vsize i = 0; i < heads.size (); i++)
+ Side_position_interface::add_support (parent, heads[i]);
+ }
}
Direction d = UP;
}
while ((flip (&d)) != UP);
+
+ /*
+ see input/regression/dot-up-voice-collision.ly
+ */
+ for (vsize i = 0; i < clash_groups[UP].size (); i++)
+ {
+ Grob *g = clash_groups[UP][i];
+ Grob *dc = Note_column::dot_column (g);
+
+ if (dc)
+ for (vsize j = i + 1; j < clash_groups[UP].size (); j++)
+ {
+ Grob *stem = Note_column::get_stem (clash_groups[UP][j]);
+ Side_position_interface::add_support (dc, stem);
+ }
+ }
+
/*
Check if chords are meshing
*/
return acc;
}
+Grob *
+Note_column::dot_column (Grob *me)
+{
+ extract_grob_set (me, "note-heads", heads);
+ for (vsize i = 0; i < heads.size (); i++)
+ {
+ Grob *dots = unsmob_grob (heads[i]->get_object ("dot"));
+ if (dots)
+ return dots->get_parent (X_AXIS);
+ }
+
+ return 0;
+}
+
Grob *
Note_column::arpeggio (Grob *me)
{
return Stencil ();
}
+MAKE_SCHEME_CALLBACK (Script_interface, calc_positioning_done, 1);
+SCM
+Script_interface::calc_positioning_done (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ if (Grob *par = me->get_parent (X_AXIS))
+ {
+ Grob *stem = Note_column::get_stem (par);
+ if (stem && Stem::first_head (stem))
+ me->set_parent (Stem::first_head (stem), X_AXIS);
+ }
+ return SCM_BOOL_T;
+}
+
MAKE_SCHEME_CALLBACK (Script_interface, calc_direction, 1);
SCM
Script_interface::calc_direction (SCM smob)
d = DOWN;
}
- if (Grob *par = me->get_parent (X_AXIS))
- {
- Grob *stem = Note_column::get_stem (par);
- if (stem && Stem::first_head (stem))
- me->set_parent (Stem::first_head (stem), X_AXIS);
- }
-
+ (void) me->get_property ("positioning-done");
return scm_from_int (d);
}
"An object that is put above or below a note",
"add-stem-support "
"avoid-slur "
+ "positioning-done "
"script-priority "
"script-stencil "
"slur "
print_buildings (buildings_);
}
+void
+Skyline::print_points () const
+{
+ vector<Offset> ps (to_points (X_AXIS));
+
+ for (vsize i = 0; i < ps.size (); i++)
+ printf ("(%f,%f)%s" , ps[i][X_AXIS], ps[i][Y_AXIS],
+ (i%2)==1 ? "\n" : " ");
+}
+
Building::Building (Real start, Real start_height, Real end_height, Real end)
{
if (isinf (start) || isinf (end))
vector<Offset>
-Skyline::to_points (Axis a) const
+Skyline::to_points (Axis horizon_axis) const
{
vector<Offset> out;
start = i->end_;
}
- if (a == Y_AXIS)
+ if (horizon_axis == Y_AXIS)
for (vsize i = 0; i < out.size (); i++)
- out[i] = Offset (out[i][Y_AXIS], out[i][X_AXIS]);
+ out[i] = out[i].swapped ();
return out;
}
return me->get_property ("stem-end-position");
}
- Real ss = Staff_symbol_referencer::staff_space (me);
- int durlog = duration_log (me);
vector<Real> a;
/* WARNING: IN HALF SPACES */
if (!no_extend_b && dir * stem_end < 0)
stem_end = 0.0;
-
- /* Make a little room if we have a upflag and there is a dot.
- previous approach was to lengthen the stem. This is not
- good typesetting practice. */
- if (!get_beam (me) && dir == UP
- && durlog > 2)
- {
- Grob *closest_to_flag = extremal_heads (me)[dir];
- Grob *dots = closest_to_flag
- ? Rhythmic_head::get_dots (closest_to_flag) : 0;
-
- if (dots)
- {
- Real dp = Staff_symbol_referencer::get_position (dots);
- Interval flag_yext = flag (me).extent (Y_AXIS) * (2 / ss) + stem_end;
-
- /* Very gory: add myself to the X-support of the parent,
- which should be a dot-column. */
-
- if (flag_yext.distance (dp) < 0.5)
- {
- Grob *par = dots->get_parent (X_AXIS);
-
- if (Dot_column::has_interface (par))
- {
- Side_position_interface::add_support (par, me);
-
- /* TODO: apply some better logic here. The flag is
- curved inwards, so this will typically be too
- much. */
- }
- }
- }
- }
-
return scm_from_double (stem_end);
}
|| unsmob_grob (me->get_object ("beam")))
return Stencil ();
+ if (!is_normal_stem (me))
+ return Stencil ();
+
/*
TODO: maybe property stroke-style should take different values,
e.g. "" (i.e. no stroke), "single" and "double" (currently, it's
-default: $(ALL_GEN_FILES) $(outdir)/emmentaler-20.otf tree-regen
+default: $(ALL_GEN_FILES) $(outdir)/emmentaler-20.otf tree-regen $(outdir)/fonts.conf
.PHONY: tree-regen
rm -f mfplain.mem mfplain.log
rm -f *.tfm *.log
+
+## fixme: why is this necessary?
$(outdir)/%.enc.in: %.enc
cp $< $@
+$(outdir)/fonts.conf:
+ echo '<fontconfig><dir>'$(shell cd $(outdir); pwd)'</dir></fontconfig>' > $@
+
$(NCSB_OTFS): $(NCSB_SOURCE_FILES) $(buildscript-dir)/pfx2ttf.fontforge
$(foreach i, $(basename $(NCSB_SOURCE_FILES)), \
$(FONTFORGE) -script $(buildscript-dir)/pfx2ttf.fontforge \
$(i).pfb $(i).afm $(outdir)/ && ) true
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; backend helpers.
-(define-public (ly:system command)
+(define-public (ly:system command . rest)
(let* ((status 0)
(dev-null "/dev/null")
(silenced (if (or (ly:get-option 'verbose)
(format #f "~a > ~a 2>&1 " command dev-null))))
(if (ly:get-option 'verbose)
(ly:message (_ "Invoking `~a'...") command))
-
- (set! status (system silenced))
+
+ (set! status
+ (if (pair? rest)
+ (system-with-env silenced (car rest))
+ (system silenced)))
+
(if (> status 0)
(begin
(ly:message (_ "`~a' failed (~a)") command status)
;; hmmm. what's the best failure option?
(throw 'ly-file-failed)))))
+(define-public (system-with-env cmd env)
+
+ "Execute CMD in fork, with ENV (a list of strings) as the environment"
+ (let*
+ ;; laziness: should use execle?
+
+ ((pid (primitive-fork)))
+ (if (= 0 pid)
+ ;; child
+ (begin
+ (environ env)
+ (system cmd))
+
+ ;; parent
+ (cdr (waitpid pid)))))
+
(define-public (sanitize-command-option str)
"Kill dubious shell quoting"
(direction . ,RIGHT)
(positioning-done . ,ly:dot-column::calc-positioning-done)
(X-extent . ,ly:axis-group-interface::width)
- (X-offset . ,ly:dot-column::side-position)
(meta . ((class . Item)
(interfaces . (dot-column-interface
axis-group-interface))))))
(stencil . ,ly:text-interface::print)
(direction . ,ly:script-interface::calc-direction)
+ (positioning-done . ,ly:script-interface::calc-positioning-done)
(X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
(self-alignment-X . 0)
(script-priority . 100)
(stencil . ,ly:text-interface::print)
(direction . ,ly:script-interface::calc-direction)
+ (positioning-done . ,ly:script-interface::calc-positioning-done)
+
(text . ,fingering::calc-text)
(font-encoding . fetaNumber)
(font-size . -5) ; don't overlap when next to heads.
;; padding set in script definitions.
(staff-padding . 0.25)
- (X-offset . ,ly:self-alignment-interface::centered-on-x-parent)
+ (X-offset . ,script-interface::calc-x-offset)
(Y-offset . ,ly:side-position-interface::y-aligned-side)
(side-axis . ,Y)
(stencil . ,ly:script-interface::print)
(direction . ,ly:script-interface::calc-direction)
+ (positioning-done . ,ly:script-interface::calc-positioning-done)
(font-encoding . fetaMusic)
(cross-staff . ,ly:script-interface::calc-cross-staff)
(meta . ((class . Item)
(stencil . ,ly:text-interface::print)
(direction . ,ly:script-interface::calc-direction)
+ (positioning-done . ,ly:script-interface::calc-positioning-done)
(outside-staff-priority . 450)
(avoid-slur . around)
(grob-interpret-markup grob
(make-fret-diagram-verbose-markup
(string-frets->description string-frets string-count)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; scripts
+
+(define-public (script-interface::calc-x-offset grob)
+ (ly:grob-property grob 'positioning-done)
+ (ly:self-alignment-interface::centered-on-x-parent grob))
ly:cluster::print
ly:cluster-beacon::height
ly:custos::print
- ly:dot-column::side-position
ly:dots::print
ly:hairpin::print
ly:hara-kiri-group-spanner::force-hara-kiri-callback