From c237b7979f5ecf255c546e1f1205ba1a74f031e7 Mon Sep 17 00:00:00 2001 From: fred Date: Tue, 26 Mar 2002 23:55:03 +0000 Subject: [PATCH] lilypond-1.3.81 --- Documentation/hacking.texi | 190 ++++++++++++++++++++++----- lily/include/property-iterator.hh | 17 +++ lily/include/translation-property.hh | 28 ++++ lily/lyric-phrasing-engraver.cc | 14 +- lily/main.cc | 8 +- lily/music-iterator.cc | 4 + lily/my-lily-lexer.cc | 2 + lily/parser.yy | 12 ++ lily/property-iterator.cc | 52 +++++++- 9 files changed, 281 insertions(+), 46 deletions(-) diff --git a/Documentation/hacking.texi b/Documentation/hacking.texi index 8c6d9d0fff..c6c0ede9ae 100644 --- a/Documentation/hacking.texi +++ b/Documentation/hacking.texi @@ -2,6 +2,7 @@ @setfilename internals.info @settitle LilyPond internals + @node Top, LilyPond internals, (dir), (dir) @top @@ -11,17 +12,14 @@ * Overview:: * mudela:: * Request_engraver:: -* Graphic elements:: -* Score elements:: -* Items:: -* Spanners:: -* Future work:: +* Backend:: * Coding standards:: * Making patches:: * Localisation:: @end menu @node LilyPond internals, , Top, Top + @menu * Overview:: Overview * mudela:: mudela @@ -65,13 +63,6 @@ file. A interesting and very big project is writing a GUI frontend to LilyPond. -@unnumberedsubsec Website designers - -The current website for LilyPond is neat and simple, but it is not very -pretty. We would like to have a website with pretty pictures, one that -looks appealing to new users. - - @chapter LilyPond internals @@ -161,6 +152,8 @@ staffs. @node mudela, Request_engraver, Overview, Top @section mudela +[FIXME: implementation has been generalised, so this is out of date] + Most information is stored in the form of a request. In music typesetting, the user might want to cram a lot more symbols on the paper than actually fits. To reflect this idea (the user asks more @@ -259,12 +252,29 @@ will add the @code{Notehead} to the @code{Stem} it just created. To decide on merging, several engravers have been grouped. Please check @file{init/engraver.ly}. +@node Backend, , , Top + + +@section The backend of LilyPond -@node Graphic elements, , , Top -@section Graphic elements +blah blah blah + +@menu +* Graphic elements:: blah +* Position and width Callbacks:: blah +* Score_element properties:: blah +* Score elements:: blah +* Items:: blah +* Spanners:: blah +* Future work:: blah +@end menu + + +@node Graphic elements, , , Backend + Music notation is composed of a sets of interrelated glyphs. In Lilypond every glyph usually is represented by one object, a so-called Graphic Object. The primary relations between graphic objects involve @@ -286,10 +296,9 @@ means that the staccato will always maintain a fixed offset wrt to the note head, whereever the head is moved to. In the same vein, all notes on a staff have their Y positions stored -relative to an abstract object called Axis_group_spanner. If the -Axis_group_spanner of one staff is moved, the absolute Y positions of -all objects in that spanner change along, in effect causing the staff -and all its contents to move as a whole. +relative to an object that groups the staff. If that object is moved, +the absolute Y positions of all objects in that spanner change along, in +effect causing the staff and all its contents to move as a whole. Each graphic object stores a pointer and an relative offset for each direction: one for the X-axis, one for the Y-axis. For example, the X @@ -323,7 +332,124 @@ Graphical_axis_groups are special graphic objects, that are designed to function as a parent. The size of a Graphical_axis_groups group is the union of its children. -@node Score elements, , , Top +@node Position and width Callbacks, , , Backend + +The positions are, as explained relative to a parent reference +point. Most positions are not known when an object is created, so these +are calculated as needed. This is done by adding a callback for a +specific direction, eg + +@example + Real + my_translate (Score_element * ptr, Axis a) + @{ + return 5.0 PT; + @} + + [..] + my_element->add_offset_callback (my_translate, Y_AXIS) +@end example + +When a call is made to @code{my_element->relative_position (obj, +Y_AXIS)}, @code{my_translate} will be called. The result is that +my_element will be translated up by 5 pt. There are numerous callbacks, +for example +@itemize @bullet +@item to offset element by staff-spaces (See class +@code{Staff_symbol_referencer}). +@item to align elements next to other groups of elements (See class +@code{Side_position_interface}) +@item to +@end itemize + +Offset callbacks can be stacked. The callbacks will be executed in the +order that they were added. + +Width and height are similarly implemted using extent callbacks. There +can be only one callback for each axis. No callback (the 0 ptr) means: +"empty in this direction". + +@node Score_element properties, , , Backend + +Score elements can have other properties besides positioning, for +example, text strings (for text objects) style settings, glyphs, padding +settings (for scripts). These settings are stored in element properties. + +Properties are stored as GUILE association lists, with symbols as keys. +Element properties can be accessed using the C++ functions + +@example + SCM get_elt_property (SCM) const; + void set_elt_property (const char * , SCM val); + void set_immutable_elt_property (const char * , SCM val); + void set_immutable_elt_property (SCM key, SCM val); + void set_elt_property (SCM , SCM val); + void set_elt_pointer (const char*, SCM val); + SCM remove_elt_property (const char* nm); +@end example + +All lookup functions identify undefined properties with GUILE +end-of-list (ie. @code{'()} in Scheme or @code{SCM_EOL} in C) + +Implementation wise, there are two kinds of properties: + +@itemize @bullet +@item mutable properties: +element properties that change from object to object. The storage of +these are private to a Score element. Typically this is used to store +lists of pointers to other objects + +@item immutable properties: +element properties that are shared across objects. The storage is +shared, and hence is read-only. Typically, this is used to store +function callbacks, and values for shared element properties are read +from @file{ly/engraver.ly}. + + + +The following is from lily 1.3.80, and it shows the settings for the bar +numbers: Bar numbers are breakable, and visible at the beginning of the +line. The setting for @code{molecule-callback} indicates that Bar_number +is implemented as a text. +@example + basicBarNumberProperties = #`( + (molecule-callback . ,Text_item::brew_molecule) + (breakable . #t) + (visibility-lambda . ,begin-of-line-visible) + ) +@end example +@end itemize + + +In 1.3.81 an music expression was added to add to the immutable property +list, eg. like this: + +@example + \pushproperty #'(basicBarNumberProperties) + #'visibility-lambda #end-of-line-visible +@end example + +This will add the entry @code{`(visibility-lambda . +,end-of-line-visible)} to the immutable property list for bar numbers, +in effect overriding the setting from @file{ly/engraver.ly}. This can be +undone as follows + +@example + \popproperty #'(basicBarNumberProperties) + #'visibility-lambda +@end example + +Note that you must accompany these statements with a proper context +selection in most cases. + + + + + + +@node Score elements, , , Backend + +[FIXME: we want to get rid of dependencies in the implementation.] Besides relative positions there are lots of other relations between elements. Lilypond does not contain other specialized relation @@ -360,7 +486,7 @@ notes, the second on the last three. The major derived classes of Score_element are Item and Spanner. An item has one horizontal position. A spanner hangs on two items. -@node Items, , , Top +@node Items, , , Backend @section Items @@ -394,7 +520,7 @@ other pointers) are substituted such that all dependencies point at the active items: either they point at the original, or they point at left and right. -@node Spanners, , , Top +@node Spanners, , , Backend @section Spanners Spanners are symbols that are of variable shape, eg. Slurs, beams, etc. @@ -405,30 +531,25 @@ All spanners are spanned on two items, called the left and right boundary item. The X reference point is the left boundary item. -@node Future work, , , Top +@node Future work, , , Backend @section Future work There are plans to unify Spanner and Item, so there will no longer be such a clear distinction between the two. Right now, Score_elements are always either Item or either Spanner. -Most of the properties of a graphic object are now member variables of -the classes involved. To offer configurability, we want to move these -variables to scheme (GUILE) variables, and no longer use C++ code to -calculate them, but use Scheme functions. - @node Coding standards, , , Top -@chapter CodingStyle - standards while programming for GNU -LilyPond +@chapter CodingStyle - standards while programming for GNU LilyPond -Functions and methods do not return errorcodes. +Functions and methods do not return errorcodes: they never crash, but +report a programming_error and try to carry on.q @unnumberedsubsec Languages -C++ and Python are preferred. Perl is not. Python code should use an -indent of 8, using TAB characters. +C++ and Python are preferred. Perl is forbidden. Python code should +use an indent of 8, using TAB characters. @unnumberedsubsec Filenames @@ -694,10 +815,7 @@ Use them. @node Making patches, , , Top -@unnumberedsec name - - -PATCHES - track and distribute your code changes +@unnumberedsec Track and distribute your code changes This page documents how to distribute your changes to GNU lilypond diff --git a/lily/include/property-iterator.hh b/lily/include/property-iterator.hh index f60632a9e8..7591fce277 100644 --- a/lily/include/property-iterator.hh +++ b/lily/include/property-iterator.hh @@ -11,6 +11,10 @@ #define PROPERTY_ITERATOR_HH #include "music-iterator.hh" + + + + /** Iterate a property. */ @@ -22,4 +26,17 @@ protected: virtual void do_process_and_next (Moment); }; +class Push_property_iterator : public Music_iterator +{ +protected: + virtual void do_process_and_next (Moment); +}; + +class Pop_property_iterator : public Music_iterator +{ +protected: + virtual void do_process_and_next (Moment); +}; + + #endif // PROPERTY_ITERATOR_HH diff --git a/lily/include/translation-property.hh b/lily/include/translation-property.hh index ffb2968a29..0b887470fc 100644 --- a/lily/include/translation-property.hh +++ b/lily/include/translation-property.hh @@ -26,4 +26,32 @@ public: VIRTUAL_COPY_CONS(Music); }; +/** + Push onto basic property list. + + symbols -- list of basic-property lists + + element-property -- element property name + + element-value -- element property value + + */ +class Push_translation_property : public Music +{ +public: +}; + +/** + Restore previous setting. + + symbols -- list of basic-property lists + + element-property -- element property name + */ +class Pop_translation_property : public Music +{ +public: +}; + + #endif // PROPERTY_HH diff --git a/lily/lyric-phrasing-engraver.cc b/lily/lyric-phrasing-engraver.cc index 5778517c68..c17f9ce515 100644 --- a/lily/lyric-phrasing-engraver.cc +++ b/lily/lyric-phrasing-engraver.cc @@ -161,9 +161,16 @@ Lyric_phrasing_engraver::acknowledge_element(Score_element_info i) if (h->has_interface (ly_symbol2scm ("lyric-syllable-interface"))) { /* what's its LyricVoice context name? */ - String lyric_voice_context_id = - get_context_id(i.origin_trans_l_->daddy_trans_l_, "LyricVoice"); - record_lyric(trim_suffix(lyric_voice_context_id), h); + String voice_context_id; + SCM voice_context_scm = i.origin_trans_l_->get_property("associatedVoice"); + if (gh_string_p (voice_context_scm)) { + voice_context_id = ly_scm2string(voice_context_scm); + } + else { + voice_context_id = get_context_id(i.origin_trans_l_->daddy_trans_l_, "LyricVoice"); + voice_context_id = trim_suffix(voice_context_id); + } + record_lyric(voice_context_id, h); return; } @@ -481,7 +488,6 @@ Syllable_group::adjust_melisma_align() break; } group_translation_f_ += translation; - printf(" now %f.\n",float(group_translation_f_)); for(int l = 0; l < lyric_list_.size(); l++) { lyric_list_[l]->translate_axis (translation, X_AXIS); } diff --git a/lily/main.cc b/lily/main.cc index 3a8c8fcf5a..c1d6d6e6ab 100644 --- a/lily/main.cc +++ b/lily/main.cc @@ -326,10 +326,12 @@ main (int argc, char **argv) setup_paths (); /* - prepare guile for heavy mem usage. + prepare guile for heavy mem usage. + + putenv is POSIX, setenv is BSD 4.3 */ - setenv ("GUILE_INIT_SEGMENT_SIZE_1", "4194304", 0); - setenv ("GUILE_MAX_SEGMENT_SIZE", "8388608", 0); + putenv ("GUILE_INIT_SEGMENT_SIZE_1=4194304"); + putenv ("GUILE_MAX_SEGMENT_SIZE=8388608"); #if KPATHSEA && HAVE_KPATHSEA_KPATHSEA_H /* diff --git a/lily/music-iterator.cc b/lily/music-iterator.cc index 9e88aeb12b..bfa597527b 100644 --- a/lily/music-iterator.cc +++ b/lily/music-iterator.cc @@ -142,6 +142,10 @@ Music_iterator::static_get_iterator_p (Music *m) p = new Property_iterator; else if (dynamic_cast (m)) p = new Change_iterator; + else if (dynamic_cast(m)) + p = new Push_property_iterator; + else if (dynamic_cast(m)) + p = new Pop_property_iterator; else if (dynamic_cast (m)) p = new Time_scaled_music_iterator; else if (dynamic_cast (m)) diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc index 7bc2a0b54b..6fe78ea1cc 100644 --- a/lily/my-lily-lexer.cc +++ b/lily/my-lily-lexer.cc @@ -58,6 +58,8 @@ static Keyword_ent the_key_tab[]={ {"notenames", NOTENAMES}, {"notes", NOTES}, {"outputproperty", OUTPUTPROPERTY}, + {"pushproperty", PUSHPROPERTY}, + {"popproperty", POPPROPERTY}, {"partial", PARTIAL}, {"paper", PAPER}, {"penalty", PENALTY}, diff --git a/lily/parser.yy b/lily/parser.yy index 03ecf130d1..bb7b882e36 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -165,6 +165,7 @@ yylex (YYSTYPE *s, void * v_l) %token PARTIAL %token PENALTY %token PROPERTY +%token PUSHPROPERTY POPPROPERTY %token PT_T %token RELATIVE %token REMOVE @@ -681,6 +682,17 @@ Simple_music: } | MUSIC_IDENTIFIER { $$ = unsmob_music ($1)->clone (); } | property_def + | PUSHPROPERTY embedded_scm embedded_scm embedded_scm { + $$ = new Push_translation_property; + $$->set_mus_property ("symbols", $2); + $$->set_mus_property ("element-property", $3); + $$->set_mus_property ("element-value", $4); + } + | POPPROPERTY embedded_scm embedded_scm { + $$ = new Pop_translation_property; + $$->set_mus_property ("symbols", $2); + $$->set_mus_property ("element-property", $3); + } | translator_change | Simple_music '*' bare_unsigned '/' bare_unsigned { $$ = $1; diff --git a/lily/property-iterator.cc b/lily/property-iterator.cc index 9f47bce0d1..0e50832e64 100644 --- a/lily/property-iterator.cc +++ b/lily/property-iterator.cc @@ -17,10 +17,56 @@ void Property_iterator::do_process_and_next (Moment m) { - Translation_property * prop = dynamic_cast (music_l_); - SCM sym = prop->get_mus_property ("symbol"); + SCM sym = music_l_->get_mus_property ("symbol"); if (gh_symbol_p(sym)) - report_to_l ()->set_property (sym, prop->get_mus_property ("value")); + report_to_l ()->set_property (sym, music_l_->get_mus_property ("value")); Music_iterator::do_process_and_next (m); } + +void +Push_property_iterator::do_process_and_next (Moment m) +{ + SCM syms = music_l_->get_mus_property ("symbols"); + SCM eprop = music_l_->get_mus_property ("element-property"); + SCM val = music_l_->get_mus_property ("element-value"); + + for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s)) + { + SCM sym = gh_car (s); + if (gh_symbol_p(sym)) + { + SCM prev = report_to_l ()->get_property (sym); + + prev = gh_cons (gh_cons (eprop, val), prev); + report_to_l ()->set_property (gh_car (s), prev); + } + } + Music_iterator::do_process_and_next (m); +} + +void +Pop_property_iterator::do_process_and_next (Moment m) +{ + SCM syms = music_l_->get_mus_property ("symbols"); + SCM eprop = music_l_->get_mus_property ("element-property"); + for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s)) + { + SCM sym = gh_car (s); + if (gh_symbol_p(sym)) + { + SCM prev = report_to_l ()->get_property (sym); + + SCM newprops= SCM_EOL ; + while (gh_pair_p (prev) && gh_caar (prev) != eprop) + { + newprops = gh_cons (gh_car (prev), newprops); + prev = gh_cdr (prev); + } + + newprops = scm_reverse_x (newprops, gh_cdr (prev)); + report_to_l ()->set_property (sym, newprops); + } + } + Music_iterator::do_process_and_next (m); +} -- 2.39.5