X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fcontext.cc;h=4dbb6e5657721e436dc4f52227d24409c62a53e8;hb=e5cc39a9a82b3c05156553173a8513db4152b1f9;hp=da83c9a98c07dc7242d3e84ae32420fe0dd939bb;hpb=82ea2eb404974976ce5d9279c8e47e1cfa8369cc;p=lilypond.git diff --git a/lily/context.cc b/lily/context.cc index da83c9a98c..4dbb6e5657 100644 --- a/lily/context.cc +++ b/lily/context.cc @@ -1,9 +1,20 @@ /* - context.cc -- implement Context + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 2004--2011 Han-Wen Nienhuys - (c) 2004--2007 Han-Wen Nienhuys + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ #include "context.hh" @@ -46,9 +57,8 @@ Context::check_removal () } } -Context::Context (Context const &src) +Context::Context (Context const & /* src */) { - (void) src; assert (false); } @@ -104,17 +114,12 @@ Context::create_unique_context (SCM name, string id, SCM operations) if (gthis && gthis->get_score_context ()) return gthis->get_score_context ()->create_unique_context (name, id, operations); - /* - TODO: use accepts_list_. - */ - vector path - = unsmob_context_def (definition_)->path_to_acceptable_context (name, get_output_def ()); - + vector path = path_to_acceptable_context (name); if (path.size ()) { Context *current = this; - // start at 1. The first one (index 0) will be us. + // Iterate through the path and create all of the implicit contexts. for (vsize i = 0; i < path.size (); i++) { SCM ops = SCM_EOL; @@ -163,15 +168,11 @@ Context::find_create_context (SCM n, string id, SCM operations) if (n == ly_symbol2scm ("Bottom")) { - Context *tg = get_default_interpreter (); + Context *tg = get_default_interpreter (id); return tg; } - /* - TODO: use accepts_list_. - */ - vector path - = unsmob_context_def (definition_)->path_to_acceptable_context (n, get_output_def ()); + vector path = path_to_acceptable_context (n); if (path.size ()) { @@ -261,8 +262,8 @@ Context::create_context_from_event (SCM sev) SCM type_scm = ev->get_property ("type"); string type = ly_symbol2string (type_scm); - vector path - = unsmob_context_def (definition_)->path_to_acceptable_context (type_scm, get_output_def ()); + vector path = path_to_acceptable_context (type_scm); + if (path.size () != 1) { programming_error (_f ("Invalid CreateContext event: Cannot create %s context", type.c_str ())); @@ -312,6 +313,25 @@ Context::create_context_from_event (SCM sev) ly_symbol2scm ("creator"), sev); } +vector +Context::path_to_acceptable_context (SCM name) const +{ + // The 'accepts elements in definition_mods_ is a list of ('accepts string), + // but the Context_def expects to see elements of the form ('accepts symbol). + SCM accepts = SCM_EOL; + for (SCM s = scm_reverse (definition_mods_); scm_is_pair (s); s = scm_cdr (s)) + if (scm_caar (s) == ly_symbol2scm ("accepts")) + { + SCM elt = scm_list_2 (scm_caar (s), scm_string_to_symbol (scm_cadar (s))); + accepts = scm_cons (elt, accepts); + } + + return unsmob_context_def (definition_)->path_to_acceptable_context (name, + get_output_def (), + accepts); + +} + Context * Context::create_context (Context_def *cdef, string id, @@ -366,7 +386,7 @@ Context::is_bottom_context () const } Context * -Context::get_default_interpreter () +Context::get_default_interpreter (string context_id) { if (!is_bottom_context ()) { @@ -381,8 +401,8 @@ Context::get_default_interpreter () t = unsmob_context_def (this->definition_); } - Context *tg = create_context (t, "", SCM_EOL); - return tg->get_default_interpreter (); + Context *tg = create_context (t, context_id, SCM_EOL); + return tg->get_default_interpreter (context_id); } return this; } @@ -460,6 +480,13 @@ Context::add_alias (SCM sym) aliases_ = scm_cons (sym, aliases_); } +/* we don't (yet) instrument context properties */ +void +Context::instrumented_set_property (SCM sym, SCM val, const char*, int, const char*) +{ + internal_set_property (sym, val); +} + void Context::internal_set_property (SCM sym, SCM val) { @@ -692,6 +719,35 @@ measure_position (Context const *context) return m; } +/* Finds the measure position after a note of length DUR that + begins at the current measure position. */ +Moment +measure_position (Context const *context, Duration const *dur) +{ + Moment pos = measure_position (context); + Rational dur_length = dur ? dur->get_length () : Rational (0); + + Moment end_pos = pos.grace_part_ < Rational(0) + ? Moment(pos.main_part_, pos.grace_part_ + dur_length) + : Moment(pos.main_part_ + dur_length, 0); + + return end_pos; +} + +int +measure_number (Context const *context) +{ + SCM barnum = context->get_property ("internalBarNumber"); + SCM smp = context->get_property ("measurePosition"); + + int bn = robust_scm2int (barnum, 0); + Moment mp = robust_scm2moment (smp, Moment (0)); + if (mp.main_part_ < Rational (0)) + bn--; + + return bn; +} + void set_context_property_on_children (Context *trans, SCM sym, SCM val) @@ -716,3 +772,13 @@ melisma_busy (Context *tr) return busy; } + +bool +check_repeat_count_visibility (Context const *context, SCM count) +{ + SCM proc = context->get_property ("repeatCountVisibility"); + return (ly_is_procedure (proc) + && to_boolean (scm_call_2 (proc, + count, + context->self_scm ()))); +}