}
Interval
-Axis_group_interface::cached_pure_height (Grob *me, int start, int end)
+Axis_group_interface::sum_partial_pure_heights (Grob *me, int start, int end)
{
Interval iv = begin_of_line_pure_height (me, start);
iv.unite (rest_of_line_pure_height (me, start, end));
}
Interval
-Axis_group_interface::rest_of_line_pure_height (Grob *me, int start, int end)
+Axis_group_interface::part_of_line_pure_height (Grob *me, bool begin, int start, int end)
{
+ Spanner *sp = dynamic_cast<Spanner*> (me);
+ SCM cache_symbol = begin
+ ? ly_symbol2scm ("begin-of-line-pure-height")
+ : ly_symbol2scm ("rest-of-line-pure-height");
+ SCM cached = sp->get_cached_pure_property (cache_symbol, start, end);
+ if (scm_is_pair (cached))
+ return robust_scm2interval (cached, Interval (0, 0));
+
SCM adjacent_pure_heights = me->get_property ("adjacent-pure-heights");
+ Interval ret;
+
+ if (!scm_is_pair (adjacent_pure_heights))
+ ret = Interval (0, 0);
+ else
+ {
+ SCM these_pure_heights = begin
+ ? scm_car (adjacent_pure_heights)
+ : scm_cdr (adjacent_pure_heights);
- if (!scm_is_pair (adjacent_pure_heights)
- || !scm_is_vector (scm_cdr (adjacent_pure_heights)))
- return Interval (0, 0);
+ if (scm_is_vector (these_pure_heights))
+ ret = combine_pure_heights (me, these_pure_heights, start, end);
+ else
+ ret = Interval (0, 0);
+ }
- return combine_pure_heights (me, scm_cdr (adjacent_pure_heights), start, end);
+ sp->cache_pure_property (cache_symbol, start, end, ly_interval2scm (ret));
+ return ret;
}
Interval
Axis_group_interface::begin_of_line_pure_height (Grob *me, int start)
{
- SCM adjacent_pure_heights = me->get_property ("adjacent-pure-heights");
-
- if (!scm_is_pair (adjacent_pure_heights)
- || !scm_is_vector (scm_car (adjacent_pure_heights)))
- return Interval (0, 0);
+ return part_of_line_pure_height (me, true, start, start + 1);
+}
- return combine_pure_heights (me, scm_car (adjacent_pure_heights), start, start+1);
+Interval
+Axis_group_interface::rest_of_line_pure_height (Grob *me, int start, int end)
+{
+ return part_of_line_pure_height (me, false, start, end);
}
Interval
we can assume additivity and cache things nicely. */
Grob *p = me->get_parent (Y_AXIS);
if (p && Align_interface::has_interface (p))
- return Axis_group_interface::cached_pure_height (me, start, end);
+ return Axis_group_interface::sum_partial_pure_heights (me, start, end);
Grob *common = unsmob_grob (me->get_object ("pure-Y-common"));
extract_grob_set (me, "pure-relevant-grobs", elts);
Grob *common, Axis);
static Interval relative_pure_height (Grob *me, int start, int end);
static Interval combine_pure_heights (Grob *me, SCM, int, int);
- static Interval cached_pure_height (Grob *me, int, int);
+ static Interval sum_partial_pure_heights (Grob *me, int, int);
static Interval begin_of_line_pure_height (Grob *me, int);
static Interval rest_of_line_pure_height (Grob *me, int, int);
+ static Interval part_of_line_pure_height (Grob *me, bool begin, int, int);
static Skyline_pair skyline_spacing (Grob *me, vector<Grob*> elements);
static void add_element (Grob *me, Grob *);
{
break_index_ = 0;
spanned_drul_.set (0, 0);
+ pure_property_cache_ = SCM_UNDEFINED;
}
Spanner::Spanner (Spanner const &s)
: Grob (s)
{
spanned_drul_.set (0, 0);
+ pure_property_cache_ = SCM_UNDEFINED;
}
Real
void
Spanner::derived_mark () const
{
+ scm_gc_mark (pure_property_cache_);
+
Direction d = LEFT;
do
if (spanned_drul_[d])
return SCM_UNSPECIFIED;
}
+SCM
+Spanner::get_cached_pure_property (SCM sym, int start, int end)
+{
+ // The pure property cache is indexed by (name start . end), where name is
+ // a symbol, and start and end are numbers referring to the starting and
+ // ending column ranks of the current line.
+ if (scm_hash_table_p (pure_property_cache_) == SCM_BOOL_F)
+ return SCM_UNDEFINED;
+
+ SCM key = scm_cons (sym, scm_cons (scm_from_int (start), scm_from_int (end)));
+ return scm_hash_ref (pure_property_cache_, key, SCM_UNDEFINED);
+}
+
+void
+Spanner::cache_pure_property (SCM sym, int start, int end, SCM val)
+{
+ if (scm_hash_table_p (pure_property_cache_) == SCM_BOOL_F)
+ pure_property_cache_ = scm_c_make_hash_table (17);
+
+ SCM key = scm_cons (sym, scm_cons (scm_from_int (start), scm_from_int (end)));
+ scm_hash_set_x (pure_property_cache_, key, val);
+}
+
ADD_INTERFACE (Spanner,
"Some objects are horizontally spanned between objects. For"
" example, slurs, beams, ties, etc. These grobs form a subtype"