]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.3.81
authorfred <fred>
Tue, 26 Mar 2002 23:55:03 +0000 (23:55 +0000)
committerfred <fred>
Tue, 26 Mar 2002 23:55:03 +0000 (23:55 +0000)
Documentation/hacking.texi
lily/include/property-iterator.hh
lily/include/translation-property.hh
lily/lyric-phrasing-engraver.cc
lily/main.cc
lily/music-iterator.cc
lily/my-lily-lexer.cc
lily/parser.yy
lily/property-iterator.cc

index 8c6d9d0fffd7ae7a6a8bed4b477023ddf4d80335..c6c0ede9ae7ad4a90d786d60bf84bc3c7bde0c23 100644 (file)
@@ -2,6 +2,7 @@
 @setfilename internals.info
 @settitle LilyPond internals
 
+
 @node Top, LilyPond internals, (dir), (dir)
 @top
 
 * 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
     
index f60632a9e8b584edadfc6858140916478dc6f892..7591fce27748d4e7e510af6bf88ec8a510031741 100644 (file)
 #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
index ffb2968a2967d98c039def18451b14f642131dd2..0b887470fc4d418729cf4bec0a70fc4073f44f5a 100644 (file)
@@ -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
index 5778517c6885d8b20db039057337f2e8d6524cda..c17f9ce5154aae60111f44c158e83e4a6b0b411d 100644 (file)
@@ -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);
     }
index 3a8c8fcf5a33e8e9ec7bf827d25b82b99840400a..c1d6d6e6abf35264691649f3684979d1a4dde735 100644 (file)
@@ -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
   /*
index 9e88aeb12b1a7c6e0bc7f94a08233fc1f1752733..bfa597527b0dd5464fdf5cd82f5bc5bc1ad27457 100644 (file)
@@ -142,6 +142,10 @@ Music_iterator::static_get_iterator_p (Music  *m)
     p = new Property_iterator;
   else if (dynamic_cast<Change_translator   *> (m))
     p = new Change_iterator;
+  else if (dynamic_cast<Push_translation_property*>(m))
+    p = new Push_property_iterator;
+  else if (dynamic_cast<Pop_translation_property*>(m))
+    p = new Pop_property_iterator;
   else if (dynamic_cast<Time_scaled_music   *> (m))
     p = new Time_scaled_music_iterator;
   else if (dynamic_cast<Grace_music *> (m))
index 7bc2a0b54b49da1a2aefabae72379ca779ea8d95..6fe78ea1ccd69bb0ee649461818d647cf1ea9ba3 100644 (file)
@@ -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},
index 03ecf130d17297707b65d72610d8ada149d96b58..bb7b882e36dc261637d8eb36c9ce13cde659a94a 100644 (file)
@@ -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;
index 9f47bce0d19037c13006ad47baee2304c71b9b05..0e50832e64a7d55013b491b3366e171c7cab123d 100644 (file)
 void
 Property_iterator::do_process_and_next (Moment m)
 {
-  Translation_property * prop = dynamic_cast<Translation_property *> (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);
+}