}
}
+vector<Grob*>
+Accidental_placement::get_break_reminder_accidentals (vector<Grob*> const &elts, Grob *left)
+{
+ vector<Grob*> br;
+ vector<Grob*> ra;
+ vector<Grob*> ret;
+
+ if (dynamic_cast<Item *> (left)->break_status_dir () != RIGHT)
+ return vector<Grob*> ();
+
+ for (vsize i = 0; i < elts.size (); i++)
+ {
+ split_accidentals (elts[i], &br, &ra);
+ ret.insert (ret.end (), br.begin (), br.end ());
+ }
+ return ret;
+}
+
/*
Accidentals are special, because they appear and disappear after
ties at will.
v.unite (Interval (where, where));
}
- /*
- TODO: support self-alignment-{Y, X}
- */
for (vsize i = 0; i < translates.size (); i++)
elems[i]->translate_axis (translates[i] - v.center (), a);
}
-/*
- Hairy function to put elements where they should be. Can be tweaked
- from the outside by setting extra-space in its
- children
-
- We assume that the children the refpoints of the children are still
- found at 0.0 -- we will fuck up with thresholds if children's
- extents are already moved to locations such as (-16, -8), since the
- dy needed to put things in a row doesn't relate to the distances
- between original refpoints.
-
- TODO: maybe we should rethink and throw out thresholding altogether.
- The original function has been taken over by
- align_to_fixed_distance ().
-*/
+/* for each grob, find its upper and lower skylines. If the grob has
+ an empty extent, delete it from the list instead. If the extent is
+ non-empty but there is no skyline available (or pure is true), just
+ create a flat skyline from the bounding box */
+static void
+get_skylines (Grob *me,
+ vector<Grob*> *const elements,
+ Axis a,
+ bool pure, int start, int end,
+ vector<Skyline_pair> *const ret)
+{
+ Grob *other_axis_common = common_refpoint_of_array (*elements, me, other_axis (a));
+ for (vsize i = elements->size (); i--;)
+ {
+ Grob *g = (*elements)[i];
+ Interval extent = g->maybe_pure_extent (g, a, pure, start, end);
+ Interval other_extent = pure ? Interval (-infinity_f, infinity_f)
+ : g->extent (other_axis_common, other_axis (a));
+ Box b = (a == X_AXIS) ? Box (extent, other_extent) : Box (other_extent, extent);
+
+ if (extent.is_empty ())
+ {
+ elements->erase (elements->begin () + i);
+ continue;
+ }
+
+ Skyline_pair skylines;
+ if (!pure
+ && Skyline_pair::unsmob (g->get_property ("skylines")))
+ skylines = *Skyline_pair::unsmob (g->get_property ("skylines"));
+ else
+ {
+ if (!pure)
+ programming_error ("no skylines for alignment-child\n");
+
+ skylines = Skyline_pair (b, 0, other_axis (a));
+ }
+
+ /* each skyline is calculated relative to (potentially) a different other_axis
+ coordinate. In order to compare the skylines effectively, we need to shift them
+ to some absolute reference point */
+ if (!pure)
+ {
+ /* this is perhaps an abuse of minimum-?-extent: maybe we should create
+ another property? But it seems that the only (current) use of
+ minimum-Y-extent is to separate vertically-aligned elements */
+ SCM min_extent = g->get_property (a == X_AXIS ? "minimum-X-extent" : "minimum-Y-extent");
+ if (is_number_pair (min_extent))
+ {
+ b[a] = ly_scm2interval (min_extent);
+ skylines.insert (b, 0, other_axis (a));
+ }
+ Real offset = g->relative_coordinate (other_axis_common, other_axis (a));
+ skylines.shift (-offset);
+ }
+
+
+ ret->push_back (skylines);
+ }
+ reverse (*ret);
+}
vector<Real>
Align_interface::get_extents_aligned_translates (Grob *me,
Direction stacking_dir = robust_scm2dir (me->get_property ("stacking-dir"),
DOWN);
- Interval threshold = robust_scm2interval (me->get_property ("threshold"),
- Interval (0, Interval::infinity ()));
+ vector<Grob*> elems (all_grobs); // writable copy
+ vector<Skyline_pair> skylines;
- vector<Interval> dims;
- vector<Grob*> elems;
+ get_skylines (me, &elems, a, pure, start, end, &skylines);
- for (vsize i = 0; i < all_grobs.size (); i++)
- {
- Interval y = all_grobs[i]->maybe_pure_extent (all_grobs[i], a, pure, start, end);
- if (!y.is_empty ())
- {
- Grob *e = dynamic_cast<Grob *> (all_grobs[i]);
-
- elems.push_back (e);
- dims.push_back (y);
- }
- }
-
- /*
- Read self-alignment-X and self-alignment-Y. This may seem like
- code duplication. (and really: it is), but this is necessary to
- prevent ugly cyclic dependencies that arise when you combine
- self-alignment on a child with alignment of children.
- */
- SCM align ((a == X_AXIS)
- ? me->get_property ("self-alignment-X")
- : me->get_property ("self-alignment-Y"));
-
- Interval total;
Real where = 0;
- Real extra_space = 0.0;
SCM extra_space_handle = scm_assq (ly_symbol2scm ("alignment-extra-space"), line_break_details);
+ Real extra_space = robust_scm2double (scm_is_pair (extra_space_handle)
+ ? scm_cdr (extra_space_handle)
+ : SCM_EOL,
+ 0.0);
- extra_space = robust_scm2double (scm_is_pair (extra_space_handle)
- ? scm_cdr (extra_space_handle)
- : SCM_EOL,
- extra_space);
-
- Real padding = robust_scm2double (me->get_property ("padding"),
- 0.0);
+ Real padding = robust_scm2double (me->get_property ("padding"), 0.0);
vector<Real> translates;
for (vsize j = 0; j < elems.size (); j++)
{
- Real dy = -dims[j][-stacking_dir];
- if (j)
- dy += dims[j - 1][stacking_dir];
-
- /*
- we want dy to be > 0
- */
- dy *= stacking_dir;
- if (j)
- dy = min (max (dy, threshold[SMALLER]), threshold[BIGGER]);
-
+ Real dy = 0;
+ if (j == 0)
+ dy = skylines[j][-stacking_dir].max_height ();
+ else
+ dy = skylines[j-1][stacking_dir].distance (skylines[j][-stacking_dir]);
where += stacking_dir * (dy + padding + extra_space / elems.size ());
- total.unite (dims[j] + where);
translates.push_back (where);
}
}
}
-
- Real center_offset = 0.0;
-
- /*
- also move the grobs that were empty, to maintain spatial order.
- */
vector<Real> all_translates;
- if (translates.size ())
+
+ if (!translates.empty ())
{
Real w = translates[0];
-
- if (scm_is_number (align))
- center_offset = total.linear_combination (scm_to_double (align));
-
for (vsize i = 0, j = 0; j < all_grobs.size (); j++)
{
if (i < elems.size () && all_grobs[j] == elems[i])
w = translates[i++];
- all_translates.push_back (w - center_offset);
+ all_translates.push_back (w);
}
}
return all_translates;
return pure_group_height (me, start, end);
}
+
+MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_skylines, 1);
+SCM
+Axis_group_interface::calc_skylines (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ extract_grob_set (me, "elements", elts);
+ return skyline_spacing (me, elts).smobbed_copy ();
+}
+
+/* whereas calc_skylines calculates skylines for axis-groups with a lot of
+ visible children, combine_skylines is designed for axis-groups whose only
+ children are other axis-groups (ie. VerticalAlignment). Rather than
+ calculating all the skylines from scratch, we just merge the skylines
+ of the children.
+*/
+MAKE_SCHEME_CALLBACK (Axis_group_interface, combine_skylines, 1);
+SCM
+Axis_group_interface::combine_skylines (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ extract_grob_set (me, "elements", elements);
+ Grob *y_common = common_refpoint_of_array (elements, me, Y_AXIS);
+
+ assert (y_common == me);
+
+ Skyline_pair ret;
+ for (vsize i = 0; i < elements.size (); i++)
+ {
+ SCM skyline_scm = elements[i]->get_property ("skylines");
+ if (Skyline_pair::unsmob (skyline_scm))
+ {
+ Real offset = elements[i]->relative_coordinate (y_common, Y_AXIS);
+ Skyline_pair other = *Skyline_pair::unsmob (skyline_scm);
+ other.raise (offset);
+ ret.merge (other);
+ }
+ }
+ return ret.smobbed_copy ();
+}
SCM
Axis_group_interface::generic_group_extent (Grob *me, Axis a)
{
+ /* trigger the callback to do skyline-spacing on the children */
+ (void) me->get_property ("skylines");
+
extract_grob_set (me, "elements", elts);
- if (a == Y_AXIS && to_boolean (me->get_property ("skyline-spacing")))
- skyline_spacing (me, elts);
Grob *common = common_refpoint_of_array (elts, me, a);
Real my_coord = me->relative_coordinate (common, a);
bool
staff_priority_less (Grob * const &g1, Grob * const &g2)
{
- int priority_1 = robust_scm2int (g1->get_property ("outside-staff-priority"), INT_MIN);
- int priority_2 = robust_scm2int (g2->get_property ("outside-staff-priority"), INT_MIN);
+ Real priority_1 = robust_scm2double (g1->get_property ("outside-staff-priority"), -infinity_f);
+ Real priority_2 = robust_scm2double (g2->get_property ("outside-staff-priority"), -infinity_f);
if (priority_1 < priority_2)
return true;
edge of the just-placed grob). Otherwise, we skip it until the next pass.
*/
static void
-add_grobs_of_one_priority (Drul_array<Skyline> *const skylines,
+add_grobs_of_one_priority (Skyline_pair *const skylines,
vector<Grob*> elements,
Grob *x_common,
Grob *y_common)
elements[i]->translate_axis (dir*dist, Y_AXIS);
}
(*skylines)[dir].insert (b, 0, X_AXIS);
- elements[i]->del_property ("outside-staff-padding");
+ elements[i]->set_property ("outside-staff-priority", SCM_BOOL_F);
last_affected_position[dir] = b[X_AXIS][RIGHT];
}
elements.erase (elements.begin () + i);
}
}
-void
+Skyline_pair
Axis_group_interface::skyline_spacing (Grob *me, vector<Grob*> elements)
{
vector_sort (elements, staff_priority_less);
Grob *x_common = common_refpoint_of_array (elements, me, X_AXIS);
Grob *y_common = common_refpoint_of_array (elements, me, Y_AXIS);
+ assert (y_common == me);
+
vsize i = 0;
vector<Box> boxes;
&& !scm_is_number (elements[i]->get_property ("outside-staff-priority")); i++)
add_boxes (elements[i], x_common, y_common, &boxes);
- Drul_array<Skyline> skylines (Skyline (boxes, 0, X_AXIS, DOWN),
- Skyline (boxes, 0, X_AXIS, UP));
+ Skyline_pair skylines (boxes, 0, X_AXIS);
for (; i < elements.size (); i++)
{
SCM priority = elements[i]->get_property ("outside-staff-priority");
add_grobs_of_one_priority (&skylines, current_elts, x_common, y_common);
}
+ return skylines;
}
ADD_INTERFACE (Axis_group_interface,
"elements "
"common-refpoint-of-elements "
"pure-relevant-elements "
- "skyline-spacing "
+ "skylines "
"cached-pure-extents "
);
TRANSLATOR_DECLARATIONS (Dynamic_engraver);
DECLARE_ACKNOWLEDGER (accidental);
- DECLARE_ACKNOWLEDGER (script);
DECLARE_ACKNOWLEDGER (stem_tremolo);
DECLARE_ACKNOWLEDGER (note_column);
DECLARE_ACKNOWLEDGER (slur);
finished_cresc_->set_bound (RIGHT, info.grob ());
}
-void
-Dynamic_engraver::acknowledge_script (Grob_info info)
-{
- if (!line_spanner_ || !script_)
- return;
-
- SCM p = info.grob ()->get_property ("script-priority");
-
- /*
- UGH.
-
- DynamicText doesn't really have a script-priority field.
- */
- if (scm_is_number (p)
- && scm_to_int (p)
- < scm_to_int (script_->get_property ("script-priority")))
- Side_position_interface::add_support (line_spanner_, info.grob ());
-}
-
ADD_ACKNOWLEDGER (Dynamic_engraver, accidental);
-ADD_ACKNOWLEDGER (Dynamic_engraver, script);
ADD_ACKNOWLEDGER (Dynamic_engraver, note_column);
ADD_ACKNOWLEDGER (Dynamic_engraver, slur);
ADD_ACKNOWLEDGER (Dynamic_engraver, stem_tremolo);
DECLARE_SCHEME_CALLBACK (alignment_callback, (SCM element));
static void add_accidental (Grob *, Grob *);
+ static vector<Grob*> get_break_reminder_accidentals (vector<Grob*> const &elts,
+ Grob *left);
static Interval get_relevant_accidental_extent (Grob *me,
Item *item_col,
Grob *acc);
#include "std-vector.hh"
#include "lily-proto.hh"
#include "grob-interface.hh"
+#include "skyline.hh"
struct Axis_group_interface
{
DECLARE_SCHEME_CALLBACK (width, (SCM smob));
DECLARE_SCHEME_CALLBACK (height, (SCM smob));
DECLARE_SCHEME_CALLBACK (pure_height, (SCM smob, SCM start, SCM end));
+ DECLARE_SCHEME_CALLBACK (calc_skylines, (SCM smob));
+ DECLARE_SCHEME_CALLBACK (combine_skylines, (SCM smob));
static Interval relative_group_extent (vector<Grob*> const &list,
Grob *common, Axis);
static Interval relative_pure_height (Grob *me, vector<Grob*> const &list,
static Interval cached_pure_height (Grob *me, vector<Grob*> const &list,
Grob *common, int, int);
- static void skyline_spacing (Grob *me, vector<Grob*> elements);
+ static Skyline_pair skyline_spacing (Grob *me, vector<Grob*> elements);
static void add_element (Grob *me, Grob *);
static void set_axes (Grob *, Axis, Axis);
static bool has_axis (Grob *, Axis);
#include "lily-proto.hh"
#include "direction.hh"
#include "grob-interface.hh"
+#include "skyline.hh"
struct Separation_item
{
DECLARE_GROB_INTERFACE();
DECLARE_SCHEME_CALLBACK(calc_skylines, (SCM));
- static vector<Box> boxes (Grob *me);
- static Interval conditional_width (Grob *, Grob *);
+ static vector<Box> boxes (Grob *me, Grob *left);
+ static Skyline conditional_skyline (Grob *, Grob *);
static Interval width (Grob *);
static Interval relative_width (Grob *, Grob *);
static Grob *extremal_break_aligned_grob (Grob *, Direction, Interval *);
void precompute ();
Building (Real start, Real start_height, Real end_height, Real end);
+ Building (Box const &b, Real horizon_padding, Axis a, Direction d);
void print () const;
Real height (Real x) const;
void leading_part (Real chop);
bool conceals_beginning (Building const &other) const;
bool conceals (Building const &other) const;
+ bool sane () const;
Building sloped_neighbour (Real horizon_padding, Direction d) const;
};
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 () const;
void merge (Skyline const &);
void insert (Box const &, Real horizon_padding, Axis);
void print () const;
void raise (Real);
+ void shift (Real);
Real distance (Skyline const &) const;
Real height (Real airplane) const;
Real max_height () const;
void set_minimum_height (Real height);
};
+class Skyline_pair
+{
+private:
+ Drul_array<Skyline> skylines_;
+
+ DECLARE_SIMPLE_SMOBS(Skyline_pair);
+public:
+ Skyline_pair ();
+ Skyline_pair (vector<Box> const &boxes, Real horizon_padding, Axis a);
+ Skyline_pair (Box const &, Real horizon_padding, Axis a);
+ void raise (Real);
+ void shift (Real);
+ void insert (Box const &, Real horizon_padding, Axis);
+ void merge (Skyline_pair const &other);
+ Skyline &operator [] (Direction d);
+ Skyline const &operator [] (Direction d) const;
+};
+
#endif /* SKYLINE_HH */
{
Grob *g = unsmob_grob (scm_car (s));
if (last)
- Side_position_interface::add_support (g, last);
+ {
+ SCM outside_staff = last->get_property ("outside-staff-priority");
+ if (scm_is_number (outside_staff))
+ {
+ /* we allow the outside-staff-priority ordering to override the
+ script-priority ordering */
+ if (!scm_is_number (g->get_property ("outside-staff-priority")))
+ g->set_property ("outside-staff-priority",
+ scm_from_double (scm_to_double (outside_staff) + 0.1));
+ }
+ else
+ Side_position_interface::add_support (g, last);
+ }
last = g;
}
Separation_item::set_skyline_distance (Drul_array<Item *> items,
Real padding)
{
- Drul_array<Skyline*> lines;
- Direction d = LEFT;
-
- do
- {
- SCM prop = items[d]->get_property ("skylines");
- lines[d] = Skyline::unsmob (index_get_cell (prop, -d));
- }
- while (flip (&d) != LEFT);
-
- Real dist = padding + lines[LEFT]->distance (*lines[RIGHT]);
+ Drul_array<Skyline_pair*> lines (Skyline_pair::unsmob (items[LEFT]->get_property ("skylines")),
+ Skyline_pair::unsmob (items[RIGHT]->get_property ("skylines")));
+ Skyline right = conditional_skyline (items[RIGHT], items[LEFT]);
+ right.merge ((*lines[RIGHT])[LEFT]);
+
+ Real dist = padding + (*lines[LEFT])[RIGHT].distance (right);
if (dist > 0)
{
Rod rod;
Separation_item::set_distance (Drul_array<Item *> items,
Real padding)
{
- if (!Item::is_non_musical (items[LEFT])
- && !Item::is_non_musical (items[RIGHT]))
- {
- set_skyline_distance (items, padding);
- return true;
- }
-
- Interval li (Separation_item::width (items[LEFT]));
- Interval ri (Separation_item::conditional_width (items[RIGHT], items[LEFT]));
- if (!li.is_empty () && !ri.is_empty ())
- {
- Rod rod;
-
- rod.item_drul_ = items;
-
- rod.distance_ = li[RIGHT] - ri[LEFT] + padding;
-
- if (rod.distance_ > 0)
- rod.add_to_cols ();
- return true;
- }
- return false;
+ set_skyline_distance (items, padding);
+ return true;
}
/*
Return the width of ME given that we are considering the object on
the LEFT.
*/
-Interval
-Separation_item::conditional_width (Grob *me, Grob *left)
+Skyline
+Separation_item::conditional_skyline (Grob *me, Grob *left)
{
- Interval w = width (me);
-
- Item *item = dynamic_cast<Item *> (me);
- Paper_column *pc = item->get_column ();
-
- extract_grob_set (me, "conditional-elements", elts);
- for (vsize i = 0; i < elts.size (); i++)
- {
- Item *il = dynamic_cast<Item *> (elts[i]);
- if (pc != il->get_column ())
- {
- programming_error ("Separation_item element from wrong column");
- continue;
- }
-
- if (to_boolean (il->get_property ("no-spacing-rods")))
- continue;
-
- if (Accidental_placement::has_interface (il))
- w.unite (Accidental_placement::get_relevant_accidental_extent (il, pc, left));
- }
-
- SCM pad = me->get_property ("padding");
-
- w.widen (robust_scm2double (pad, 0.0));
- return w;
+ vector<Box> bs = boxes (me, left);
+ return Skyline (bs, 0.1, Y_AXIS, LEFT);
}
Separation_item::calc_skylines (SCM smob)
{
Item *me = unsmob_item (smob);
- SCM lines = scm_cons (SCM_BOOL_F,SCM_BOOL_F);
-
- Direction d = LEFT;
- vector<Box> bs = boxes (me);
- do
- {
- /* todo: the horizon_padding is somewhat arbitrary */
- Skyline l (bs, 0.1, Y_AXIS, d);
- index_set_cell (lines, d, l.smobbed_copy ());
- }
- while (flip (&d) != LEFT);
-
- return lines;
+ vector<Box> bs = boxes (me, 0);
+ /* todo: the horizon_padding is somewhat arbitrary */
+ return Skyline_pair (bs, 0.1, Y_AXIS).smobbed_copy ();
}
-
+/* if left is non-NULL, get the boxes corresponding to the
+ conditional-elements (conditioned on the grob LEFT). This
+ sounds more general than it is: conditional-elements are
+ always accidentals attached to a tied note.
+*/
vector<Box>
-Separation_item::boxes (Grob *me)
+Separation_item::boxes (Grob *me, Grob *left)
{
Item *item = dynamic_cast<Item *> (me);
int very_large = INT_MAX;
Paper_column *pc = item->get_column ();
vector<Box> out;
- extract_grob_set (me, "elements", elts);
+ extract_grob_set (me, left ? "conditional-elements" : "elements", read_only_elts);
+ vector<Grob*> elts;
+
+ if (left)
+ elts = Accidental_placement::get_break_reminder_accidentals (read_only_elts, left);
+ else
+ elts = read_only_elts;
Grob *ycommon = common_refpoint_of_array (elts, me, Y_AXIS);
continue;
Interval y (il->pure_height (ycommon, 0, very_large));
- Box b (il->extent (pc, X_AXIS), y);
+ Interval x (il->extent (pc, X_AXIS));
- out.push_back (b);
+ SCM padding = elts[i]->get_property ("padding");
+ x.widen (robust_scm2double (padding, 0));
+
+ out.push_back (Box (x, y));
}
return out;
Separation_item::width (Grob *me)
{
SCM sw = me->get_property ("X-extent");
- if (is_number_pair (sw))
- return ly_scm2interval (sw);
-
- Item *item = dynamic_cast<Item *> (me);
- Paper_column *pc = item->get_column ();
- Interval w;
-
- extract_grob_set (me, "elements", elts);
- for (vsize i = 0; i < elts.size (); i++)
- {
- Item *il = dynamic_cast<Item *> (elts[i]);
- if (pc != il->get_column ())
- {
- /* this shouldn't happen, but let's continue anyway. */
- programming_error ("Separation_item: I've been drinking too much");
- continue; /*UGH UGH*/
- }
-
- if (to_boolean (il->get_property ("no-spacing-rods")))
- continue;
-
- Interval iv (il->extent (pc, X_AXIS));
- if (!iv.is_empty ())
- w.unite (iv);
- }
-
- SCM pad = me->get_property ("padding");
-
- w.widen (robust_scm2double (pad, 0.0));
-
- me->set_property ("X-extent", ly_interval2scm (w));
-
- return w;
+ return ly_scm2interval (sw);
}
Interval
precompute ();
}
+Building::Building (Box const &b, Real horizon_padding, Axis horizon_axis, Direction sky)
+{
+ Real height = sky * b[other_axis (horizon_axis)][sky];
+
+ iv_ = b[horizon_axis];
+ iv_.widen (horizon_padding + EPS);
+ height_[LEFT] = height;
+ height_[RIGHT] = height;
+
+ if (sane ())
+ precompute ();
+}
+
void
Building::precompute ()
{
return Building (left, left_height, right_height, right);
}
+bool
+Building::sane () const
+{
+ return approx_less_than (iv_[LEFT], iv_[RIGHT])
+ && !isinf (height_[RIGHT])
+ && !isinf (height_[LEFT]);
+}
+
static void
skyline_trailing_part (list<Building> *sky, Real x)
{
for (vsize i = 0; i < boxes.size (); i++)
{
- Interval iv = boxes[i][horizon_axis];
- Real height = sky * boxes[i][other_axis (horizon_axis)][sky];
-
- iv.widen (horizon_padding);
- if (!iv.is_empty () && !isinf (height) && !approx_equal (iv[LEFT], iv[RIGHT]))
+ Building front (boxes[i], horizon_padding, horizon_axis, sky);
+ if (front.sane ())
{
- iv.widen (EPS);
- Building front = Building (iv[LEFT], height, height, iv[RIGHT]);
bldgs.push_front (front);
if (horizon_padding > 0 && !isinf (front.iv_.length ()))
{
assert (is_legal_skyline ());
}
+Skyline::Skyline (Box const &b, Real horizon_padding, Axis horizon_axis, Direction sky)
+{
+ sky_ = sky;
+ Building front (b, 0, horizon_axis, sky);
+ single_skyline (front, horizon_padding, &buildings_);
+}
+
void
Skyline::merge (Skyline const &other)
{
{
list<Building> other_bld;
list<Building> my_bld;
- Interval iv = b[a];
- Real height = sky_ * b[other_axis (a)][sky_];
-
- assert (!iv.is_empty ());
- iv.widen (EPS);
my_bld.splice (my_bld.begin (), buildings_);
- single_skyline (Building (iv[LEFT], height, height, iv[RIGHT]), horizon_padding, &other_bld);
+ single_skyline (Building (b, 0, a, sky_), horizon_padding, &other_bld);
internal_merge_skyline (&other_bld, &my_bld, &buildings_);
assert (is_legal_skyline ());
}
assert (is_legal_skyline ());
}
+void
+Skyline::shift (Real r)
+{
+ list<Building>::iterator end = buildings_.end ();
+ for (list<Building>::iterator i = buildings_.begin (); i != end; i++)
+ {
+ i->iv_[LEFT] += r;
+ i->iv_[RIGHT] += r;
+ }
+}
+
Real
Skyline::distance (Skyline const &other) const
{
return out;
}
+Skyline_pair::Skyline_pair ()
+ : skylines_ (Skyline (DOWN), Skyline (UP))
+{
+}
+
+Skyline_pair::Skyline_pair (vector<Box> const &boxes, Real padding, Axis a)
+ : skylines_ (Skyline (boxes, padding, a, DOWN), Skyline (boxes, padding, a, UP))
+{
+}
+
+Skyline_pair::Skyline_pair (Box const &b, Real padding, Axis a)
+ : skylines_ (Skyline (b, padding, a, DOWN), Skyline (b, padding, a, UP))
+{
+}
+
+void
+Skyline_pair::raise (Real r)
+{
+ skylines_[UP].raise (r);
+ skylines_[DOWN].raise (r);
+}
+
+void
+Skyline_pair::shift (Real r)
+{
+ skylines_[UP].shift (r);
+ skylines_[DOWN].shift (r);
+}
+
+void
+Skyline_pair::insert (Box const &b, Real padding, Axis a)
+{
+ skylines_[UP].insert (b, padding, a);
+ skylines_[DOWN].insert (b, padding, a);
+}
+
+void
+Skyline_pair::merge (Skyline_pair const &other)
+{
+ skylines_[UP].merge (other[UP]);
+ skylines_[DOWN].merge (other[DOWN]);
+}
+
+Skyline&
+Skyline_pair::operator [] (Direction d)
+{
+ return skylines_[d];
+}
+
+Skyline const&
+Skyline_pair::operator [] (Direction d) const
+{
+ return skylines_[d];
+}
+
/****************************************************************/
IMPLEMENT_TYPE_P (Skyline, "ly:skyline?");
IMPLEMENT_DEFAULT_EQUAL_P (Skyline);
+IMPLEMENT_SIMPLE_SMOBS (Skyline_pair);
+IMPLEMENT_TYPE_P (Skyline_pair, "ly:skyline-pair?");
+IMPLEMENT_DEFAULT_EQUAL_P (Skyline_pair);
+
SCM
Skyline::mark_smob (SCM)
{
return 1;
}
+
+SCM
+Skyline_pair::mark_smob (SCM)
+{
+ return SCM_EOL;
+}
+
+int
+Skyline_pair::print_smob (SCM s, SCM port, scm_print_state *)
+{
+ Skyline_pair *r = (Skyline_pair *) SCM_CELL_WORD_1 (s);
+ (void) r;
+
+ scm_puts ("#<Skyline-pair>", port);
+ return 1;
+}
object.")
(side-axis ,number? "If the value is #X (or equivalently 1), the object is placed horizontally next to the other object. If the value is #Y or 0, it is placed vertically.")
(size ,number? "Size of object, relative to standard size.")
- (skylines ,pair? "A pair of lists of (x height) pairs.")
+ (skylines ,ly:skyline-pair? "Two skylines, one above and one below this grob (or, for some grobs, to the left and to the right).")
(slope ,number? "The slope of this object.")
(slur-padding ,number? "Extra distance between slur and script.")
(space-alist ,list? "A table that specifies distances between
(spaceable-staves ,ly:grob-array? "Objects to be spaced during page layout.")
(skyline-distance ,number? "The distance between this staff and the next one, as determined by a skyline algorithm.")
(skyline-horizontal-padding ,number? "For determining the vertical distance between 2 staves, it is possible to have a configuration which would result in a tight interleaving of grobs from the top staff and the bottom staff. The larger this parameter is, the farther apart the staves will be placed in such a configuration.")
- (skyline-spacing ,boolean? "When true, this axis-group will vertically space its children
-using a skyline algorithm.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
. (
(axes . (,Y))
(Y-extent . ,ly:axis-group-interface::height)
+ (skylines . ,ly:axis-group-interface::calc-skylines)
(meta . ((class . Spanner)
(interfaces . (axis-group-interface
))))))
(font-shape . italic)
(avoid-slur . around)
(no-spacing-rods . #t)
- (script-priority . 100)
(outside-staff-priority . 250)
(meta . ((class . Item)
(interfaces . (font-interface
(Y-offset . ,ly:side-position-interface::y-aligned-side)
(stencil . ,ly:text-interface::print)
-
- ;; no Y dimensions, because of lyrics under tenor clef.
- (Y-extent . (0 . 0))
(font-shape . italic)
(padding . 0.6)
(staff-padding . 0.2)
(axes . (0 1))
(X-extent . ,ly:axis-group-interface::width)
(Y-extent . ,ly:axis-group-interface::height)
- (skyline-spacing . #t)
+ (skylines . ,ly:axis-group-interface::calc-skylines)
(skyline-horizontal-padding . 1.0)
(meta . ((class . System)
(interfaces . (system-interface
(Y-extent . ,ly:axis-group-interface::height)
(X-extent . ,ly:axis-group-interface::width)
(stacking-dir . -1)
- (padding . 0.1)
+ (padding . 0.1)
+ (skylines . ,ly:axis-group-interface::combine-skylines)
(meta . ((class . Spanner)
(interfaces . (align-interface
axis-group-interface))))))
(Y-offset . ,ly:hara-kiri-group-spanner::force-hara-kiri-callback)
(Y-extent . ,ly:hara-kiri-group-spanner::y-extent)
(X-extent . ,ly:axis-group-interface::width)
- (skyline-spacing . #t)
+ (skylines . ,ly:axis-group-interface::calc-skylines);
(meta . ((class . Spanner)
(interfaces . (axis-group-interface
hara-kiri-group-spanner-interface
(define pure-print-callbacks
(list
+ ly:bar-line::print
ly:note-head::print
ly:accidental-interface::print
ly:dots::print
(ly:stencil? sten)
(memq sten pure-print-callbacks))
(ly:grob::stencil-height grob)
-
'(0 . 0))))
(define pure-conversions-alist