From: fred Date: Wed, 27 Mar 2002 00:34:30 +0000 (+0000) Subject: lilypond-1.3.116 X-Git-Tag: release/1.5.59~1045 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=18f112dfc3763c575c2f738b0dd165dba29c2e15;p=lilypond.git lilypond-1.3.116 --- diff --git a/Documentation/hacking.texi b/Documentation/hacking.texi index a3c3567400..79ff8c1879 100644 --- a/Documentation/hacking.texi +++ b/Documentation/hacking.texi @@ -11,7 +11,6 @@ * LilyPond internals:: * Overview:: * Request_engraver:: -* Backend:: * Coding standards:: * Making patches:: * Localisation:: @@ -233,296 +232,6 @@ 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 - - - -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 -@unnumberedsubsec - -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 -positions: - -@itemize @asis -@item consecutive notes are printed left to right, grouped in a staff -@item simultaneous notes are horizontally aligned (internally grouped in -a paper column). -@item the staccato mark is horizontally centered on the note it applies -to. -@end itemize - -The abstract encoding of such relations is done with the concept -@dfn{reference point}. The reference point (in X direction) of the -staccato mark is the note it applies to. The (X) position of the -staccato mark is stored relative to the position of the note head. This -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 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 -parent of a Note_head usually is a Note_column. The X parent of a -Note_column usually is either a Collision or a Paper_column. The X -parent of a Collision usually is a Paper_column. If the Collision -moves, all Note_heads that have that Collision as parent also move, but -the absolute position of the Paper_column does not change. - -To build a graphical score with Graphic_elements, conceptually, one -needs to have one Root object (in Lilypond: Line_of_score), and -recursively attach objects to the Root. However, due to the nature -of the context selection mechanisms, it turns out to be more -advantageous to construct the tree the other way around: first small -trees (note heads, barlines etc.) are created, and these are -subsequently composed into larger trees, which are finally hung on a -Paper_column (in X direction) or Line_of_score (in Y direction). - -The structure of the X,Y parent relations are determined by the -engravers and notation contexts: - -The most important X-axis parent relation depends on the timing: notes -that come earlier are attached to Paper_column that will be positioned -more to the left. - -The most important Y-axis relation depends on containment of contexts: -notes (created in a Thread or Voice context) are put in the staff where -the originating context lives in. - -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 Position and width Callbacks, , , Backend -@unnumberedsubsec - -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 implemented 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 -@unnumberedsubsec - -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 -@unnumberedsubsec - -[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 -management (Like the relative positioning code). Instead, objects can -be connected through dependencies, which sets the order in which objects -are to be processed. - -Example: the direction of a beamed stem should equal the direction of -the beam. When the stem is a added to the beam, a dependency on the -beam is set in the stem: this means that @code{Beam::do_pre_processing -()} (which does various direction related things) will be called before -@code{Stem::do_pre_processing ()}. - -The code that manages dependencies resides in the class -@code{Score_element}, a derived class of @code{Graphical_element}. The -bulk of the code handles line breaking related issues. - -To sketch the problems with line breaking: suppose a slur spans a line -break, -@example - -c4( c'''' c | \break d d )d - -@end example -In this case, the slur will appear as two parts, the first part spanning -the first three notes (the @code{c}s), the second spanning the last -three (the @code{d}s). Within Lilypond this is modeled as breaking the -slur in parts: from the Original slur, two new clones of the old slur -are made. Initially both clones depend on the six notes. After the -hairy code in Score_element, Spanner and Item which does substitutions -in sets of dependencies, the first clone depends on the first three -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, , , Backend -@section Items - - - -An item is a score element that is associated with only one -Paper_column. Examples are note heads, clefs, super and superscripts, etc. -Item is a derived class of Score_element. - -The shape of an item is known before the break calculations, and line -spacing depends on the size of items: very wide items need more space -than very small ones. - -An additional complication is the behavior of items at linebreaks. For -example, when you do a time signature change, you get only one symbol. -If it occurs at a linebreak, the new time signature must be printed both -before and after the linebreak. Other `breakable symbols' such as -clefs, and bar lines also exhibit this behavior. - -if a line of music is broken, the next line usually gets a clef. So in -TeX terms, the clef is a postbreak. The same thing happens with meter -signs: Normally the meter follows the bar. If a line is broken at that -bar, the bar along with the meter stays on the "last" line, but the next -line also gets a meter sign after the clef. To support this, -breakable items are generated in the three versions: original -(unbroken), left (before line break) and right (after line break). -During the line spacing, these versions are used to try how the spacing -of a line works out. - -Once the definitive spacing is determined, dependencies (and various -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, , , Backend -@section Spanners - -Spanners are symbols that are of variable shape, eg. Slurs, beams, etc. -Spanners is a derived class of Score_element. - -The final shape can only be determined after the line breaking process. -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, , , 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. - @node Coding standards, , , Top @chapter CodingStyle - standards while programming for GNU LilyPond @@ -610,65 +319,12 @@ the @code{type} is a Hungarian notation postfix for @code{Type}. See below Macros should be written completely in uppercase -The code should not be compilable if proper macro declarations are not -included. - -Don't laugh. It took us a whole evening/night to figure out one of -these bugs, because we had a macro that looked like -@code{DECLARE_VIRTUAL_FUNCTIONS ()}. - @unnumberedsubsec Broken code Broken code (hardwired dependencies, hardwired constants, slow algorithms and obvious limitations) should be marked as such: either with a verbose TODO, or with a short "ugh" comment. -@unnumberedsubsec Comments - -The source is commented in the DOC++ style. Check out doc++ at -@uref{http://www.zib.de/Visual/software/doc++/index.html} - -@example - - /* - C style comments for multiline comments. - They come before the thing to document. - [...] - */ - - /** - short description. - Long class documentation. - (Hungarian postfix) - - TODO Fix boring_member () - */ - class Class @{ - /** - short description. - long description - */ - - Data data_member_; - - /** - short memo. long doco of member () - @@param description of arguments - @@return Rettype - */ - Rettype member (Argtype); - - /// memo only - boring_member () @{ - data_member_ = 121; // ugh - @} - @}; - -@end example - - -Unfortunately most of the code isn't really documented that good. - @unnumberedsec Hungarian notation naming convention Proposed is a naming convention derived from the so-called diff --git a/lily/multi-measure-rest-engraver.cc b/lily/multi-measure-rest-engraver.cc index 460ccec319..b651d9f34e 100644 --- a/lily/multi-measure-rest-engraver.cc +++ b/lily/multi-measure-rest-engraver.cc @@ -31,6 +31,7 @@ public: protected: virtual void acknowledge_grob (Grob_info i); virtual bool try_music (Music*); + virtual void process_music (); virtual void stop_translation_timestep (); virtual void start_translation_timestep (); virtual void finalize (); @@ -93,9 +94,9 @@ Multi_measure_rest_engraver::try_music (Music* req_l) } void -Multi_measure_rest_engraver::create_grobs () +Multi_measure_rest_engraver::process_music () { - if (new_req_l_ && stop_req_l_) + if (new_req_l_ && stop_req_l_) stop_req_l_ = 0; if (new_req_l_) @@ -113,6 +114,12 @@ Multi_measure_rest_engraver::create_grobs () new_req_l_ =0; } +} + +void +Multi_measure_rest_engraver::create_grobs () +{ + if (busy_span_req_l_ && !mmrest_p_) { mmrest_p_ = new Spanner (get_property ("MultiMeasureRest")); @@ -138,7 +145,7 @@ Multi_measure_rest_engraver::stop_translation_timestep () { typeset_grob (mmrest_p_); /* - must keep mmrest_p_ around to set measures_i_ + we must keep mmrest_p_ around to set measure-count. */ } if (lastrest_p_) diff --git a/lily/music.cc b/lily/music.cc index d4b7d7b166..38ecc7f5e2 100644 --- a/lily/music.cc +++ b/lily/music.cc @@ -81,11 +81,28 @@ Music::length_mom () const return 0; } +void +print_alist (SCM a, SCM port) +{ + for (SCM s = a; gh_pair_p (s); s = gh_cdr (s)) + { + scm_display (gh_caar (s), port); + scm_puts (" = ", port); + scm_write (gh_cdar (s), port); + scm_puts ("\n", port); + } +} + int Music::print_smob(SCM s, SCM p, scm_print_state*) { scm_puts ("#mutable_property_alist_, p); + print_alist (m->immutable_property_alist_, p); + scm_puts (">",p); return 1; } diff --git a/lily/parser.yy b/lily/parser.yy index 5d6485132a..31894f773a 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -1624,7 +1624,7 @@ FIXME: location is one off, since ptich & duration don't contain origin refs. Request_chord * rqc2 = new Request_chord (SCM_EOL); rqc2->set_mus_property ("elements", gh_list (sk->self_scm (), SCM_UNDEFINED));; Request_chord * rqc3 = new Request_chord(SCM_EOL); - rqc2->set_mus_property ("elements", gh_list (sp2->self_scm (), SCM_UNDEFINED));; + rqc3->set_mus_property ("elements", gh_list (sp2->self_scm (), SCM_UNDEFINED));; SCM ms = gh_list (rqc1->self_scm (), rqc2->self_scm (), rqc3->self_scm (), SCM_UNDEFINED);