]> git.donarmstrong.com Git - lilypond.git/blob - Documentation/user/internals.itely
9ecae65478ce5597b791675305f8a76c5f63de25
[lilypond.git] / Documentation / user / internals.itely
1 @c -*-texinfo-*-
2 @c Note:
3 @c
4 @c A menu is needed before every deeper *section nesting of @nodes
5 @c Run M-x texinfo-all-menus-update
6 @c to automagically fill in these menus
7 @c before saving changes
8
9
10 @node Internals
11 @chapter Internals
12
13
14 When translating the input to notation, there are number of distinct
15 phases.  We list them here:
16
17 @table @b
18
19 @item Parsing:
20
21 The LY file is read, and converted to a list of @code{Scores}, which
22 each contain @code{Music} and paper/midi-definitions. Here @code{Music},
23 @code{Pitch} and @code{Duration}  objects are created.
24
25 @item Interpreting music
26 @cindex interpreting music
27
28 All music events are "read" in the same order as they would be played
29 (or read from paper). At every step of the interpretation, musical
30 events are delivered to
31 interpretation contexts,
32 @cindex engraver
33 which use them to build @code{Grob}s (or MIDI objects, for MIDI output).
34
35 In this stage @code{Music_iterators} do a traversal of the @code{Music}
36 structure. The music events thus encountered are reported to
37 @code{Translator}s, a set of objects that collectively form interpretation
38 contexts.
39
40
41 @item Prebreaking
42
43 @cindex prebreaking
44
45 At places where line breaks may occur, clefs and bars are prepared for
46 a possible line break. 
47
48 @item Preprocessing
49
50 @cindex preprocessing
51
52 In this stage, all information that is needed to determine line breaking
53 is computed. 
54
55 @item Break calculation:
56
57 The lines and horizontal positions of the columns are determined.
58
59 @item Breaking
60
61 Relations between all grobs are modified to reflect line breaks: When a
62 spanner, e.g. a slur, crosses a line-break, then the spanner is "broken
63 into pieces", for every line that the spanner is in, a copy of the grob
64 is made. A substitution process redirects all grob-reference so that
65 each spanner grob will only reference other grobs in the same line.
66
67 @item Outputting:
68
69 All vertical dimensions and spanning objects are computed, and all grobs
70 are output, line by line. The output is encoded in the form of
71 @code{Molecule}s
72
73 @end table
74
75 The data types that are mentioned here are all discussed in this
76 section.
77
78 @menu
79 * Grobs::                       Graphical object  
80 * Molecules::                   Molecules are stand-alone descriptions of output
81 @end menu
82
83 @node Grobs
84 @section Grobs
85
86 This section is about Grobs (short for Graphical Objects), which are
87 formatting objects used to create the final output. This material is
88 normally the domain of LilyPond gurus, but occasionally, a normal user
89 also has to deal with grobs.
90
91 The most simple interaction with Grobs are when you use
92 @code{\override}:
93
94 @example
95         \property Voice.Stem \override #'direction = #1
96 @end example
97
98 This piece of lily input causes all stem objects to be stem-up
99 henceforth.  In effect, you are telling lilypond to extend the definition
100 of the `Stem' grob with the setting @code{direction := 1}.
101
102 @menu
103 * What is a grob?::             
104 * Callbacks::                   
105 * Setting grob properties::     
106 * Grob interfaces::             
107 * Items and Spanners::          
108 * Grob Scheme functions::       
109 @end menu
110
111
112
113 @node What is a grob?
114 @subsection What is a grob?
115
116 In music notation, lots of symbols are related in some way.  You can
117 think of music notation as a graph where nodes are formed by the
118 symbols, and the arcs by their relations. A grob is a node in that graph.
119 The directed edges in the graph are formed by references to other grobs
120 (i.e. pointers).
121 This big graph of grobs specifies the notation problem. The solution of
122 this problem is a description of the printout in closed form, i.e. a
123 list of values.  These values are Molecules. (see @ref{Molecules})
124
125 All grobs have an X and Y-position on the page.  These X and Y positions
126 are stored in a relative format, so they can easily be combined by
127 stacking them, hanging one grob to the side of another, and coupling
128 them into a grouping-grob.
129
130 Each grob has a reference point (a.k.a.  parent): the position of a grob
131 is stored relative to that reference point. For example the X-reference
132 point of a staccato dot usually is the note head that it applies
133 to. When the note head is moved, the staccato dot moves along
134 automatically.
135
136 If you keep following offset reference points, you will always end up at
137 the root object. This root object is called @code{Line_of_score}, and it
138 represents a system (i.e. a line of music).
139
140 All grobs carry a set of grob-properties.  In the Stem example above,
141 the property @code{direction} is set to value @code{1}.  The function
142 that draws the symbol (@code{Stem::brew_molecule}) uses the value of
143 @code{direction} to determine how to print the stem and the flag.  The
144 appearance of a grob is determined solely by the values of its
145 properties.
146
147 A grob is often associated with a symbol, but some grobs do not print
148 any symbols. They take care of grouping objects. For example, there is a
149 separate grob that stacks staves vertically. The @code{NoteCollision}
150 is also an abstract grob: it only moves around chords, but doesn't print
151 anything.
152
153 A complete list of grob types is found in the generated documentation.
154
155
156 @node Callbacks
157 @subsection Callbacks
158
159 Offsets of grobs are relative to a parent reference point. Most
160 positions are not known when an object is created, so these are
161 calculated as needed. This is done by adding a callback for a specific
162 direction.
163
164 Suppose you have the following code in a .ly file.
165 @example
166         #(define (my-callback gr axis)
167                 (*  2.0 (get-grob-property gr 'direction))
168         )
169
170 ....
171
172         \property Voice.Stem \override #'Y-offset-callbacks = #(list
173                         my-callback)
174 @end example
175
176 When the Y-offset of a Stem object is needed, LilyPond will
177 automatically execute all callbacks for that object. In this case, it
178 will find @code{my-callback}, and execute that. The result is that the
179 stem is translated by two staff spaces in its direction.
180
181 (note: @code{Y-offset-callbacks} is also a property)
182
183
184
185 Offset callbacks can be stacked, i.e.
186
187 @example
188         \property .... \override #'Y-offset-callbacks = #(list
189                 callback1 callback2 callback3)
190
191 @end example
192
193 The callbacks will be executed in the order @code{callback3 callback2
194 callback1}. This is used for quantized positioning: the staccato dot is
195 above or below a note head, and it must not be on a staff-line.  To
196 achieve this, the staccato dot has two callbacks: one that positions the
197 grob above or below the note head, and one that rounds the Y-position of
198 the grob to the nearest open space.
199
200 Similarly, the size of a grob are determined through callbacks, settable
201 with grob properties @code{X-extent-callback} and
202 @code{Y-extent-callback}.  There can be only one extent-callback for
203 each axis. No callback (Scheme value @code{#f}) means: "empty in this
204 direction". If you fill in a pair of numbers, that pair hard-codes the
205 extent in that coordinate.
206
207
208 @node Setting grob properties
209 @subsection Setting grob properties
210
211 Grob properties are stored as GUILE association lists, with symbols as
212 keys.  In GUILE you can access these using functions described in
213 Section @ref{Grob Scheme functions}.  From C++, grob properties can be
214 accessed using these functions:
215
216 @example
217   SCM  get_grob_property (SCM) const;
218   void set_grob_property (const char * , SCM val);
219   void set_immutable_grob_property (const char * , SCM val);
220   void set_immutable_grob_property (SCM key, SCM val);  
221   void set_grob_property (SCM , SCM val);  
222   void set_grob_pointer (const char*, SCM val);
223   SCM  remove_grob_property (const char* nm);
224 @end example
225
226 All lookup functions identify undefined properties with end-of-list
227 (i.e. @code{'()} in Scheme or @code{SCM_EOL} in C)
228
229 Properties are stored in two ways:
230 @itemize @bullet
231 @item mutable properties.
232 Grob properties that change from object to object. The storage of
233 these are private to a grob. For example pointers to other grobs are
234 always stored in the mutable properties.
235
236 @item immutable properties.
237 Grob properties that are shared across different grobs of the same
238 type. The storage is shared, and hence it is read-only. Typically, this
239 is used to store function callbacks, and default settings. They are
240 initially read from @file{scm/grob-description.scm}.
241 @end itemize
242
243 You can change immutable grob properties with the \override syntax:
244
245 @example
246         \property Voice.Stem \override #'direction = #1
247 @end example
248
249 This will push the entry @code{'(direction . 1)} on the immutable
250 property list for stems, in effect overriding the setting from
251 @file{scm/grob-description.scm}. This can be undone by 
252
253 @example
254         \property Voice.stem \revert #'direction
255 @end example
256
257 There is also a shorthand,
258
259 @example
260         \property Context.GrobType \set #'prop = #VAL
261 @end example
262
263 this does a @code{\revert} followed by a @code{\override}
264
265 You can change mutable properties with \outputproperty. This construct
266 looks like
267
268 @example
269         \context ContextName \outputproperty @var{pred} #@var{sym} = #@var{val}
270 @end example
271
272 In this case, in every grob that satisfies @var{pred}, the grob property
273  @var{sym} is set to @var{val}.  For example
274
275 @example
276         \outputproperty
277                 #(lambda (gr) (string? (ly-get-grob-property gr
278                         'text)))
279                 #'extra-offset = #'(-1.0 . 0.0)
280 @end example
281
282 This shifts all grobs that have a @code{text} property one staff
283 space to the left. This mechanism is rather clumsy to use, but it allows
284 you tweak any setting of any grob.
285
286
287 @node Grob interfaces
288 @unnumberedsubsec Grob interfaces
289
290 Grob properties form a name space where you can set variables per
291 object.  Each object however, may have multiple functions. For example,
292 consider a dynamic symbol, such @code{\ff} (fortissimo). It is printed
293 above or below the staff, it is a dynamic sign, and it is a kind of
294 text.
295
296 To reflect this different functions of a grob, procedures and variables
297 are grouped into so-called interfaces.  The dynamic text for example
298 supports the  following interfaces:
299 @table @code 
300 @item font-interface
301   The glyph is built from characters from a font, hence the
302 @code{font-interface}. For objects supporting @code{font-interface}, you
303 can select alternate fonts by setting @code{font-style},
304 @code{font-point-size}, etc.
305
306 @item dynamic-interface
307   Dynamic interface is not associated with any variable or function in
308 particular, but this makes it possible to distinguish this grob from
309 other similar grobs (like @code{TextScript}), that have no meaning of
310 dynamics.
311
312 @item text-interface
313   This interface is for texts that are to be set using special routines
314 to stack text into lines, using kerning, etc.
315
316 @item general-grob-interface
317   This interface is supported by all grob types.
318 @end table
319
320
321
322 @node Items and Spanners
323 @unnumberedsubsec Items and Spanners
324
325 Grobs can also be distinguished in their role in the horizontal spacing.
326 Many grobs define constraints on the spacing by their sizes. For
327 example, note heads, clefs, stems, and all other symbols with a fixed
328 shape.  These grobs form a subtype called @code{Item}.
329
330 Other grobs have a shape that depends on the horizontal spacing. For
331 example, slur, beam, tie, etc. These grobs form a subtype called
332 @code{Spanner}. All spanners have two span-points (these must be
333 @code{Item}s), one on the left and one on the right. The left bound is
334 also the X-reference point of the spanner.
335
336 Some items need special treatment for line breaking. For example, a
337 clef is normally only printed at the start of a line (i.e. after a line
338 break).  To model this, `breakable' items (clef, key signature, bar lines,
339 etc.) are copied twice. Then we have three versions of each breakable
340 item: one version if there is no line break, one version that is printed
341 before the line break (at the end of a system), one version that is
342 printed after the line break.
343
344 Whether these versions are visible and take up space, is determined by
345 the outcome of the @code{visibility-lambda}. This grob property is a
346 function taking a direction (-1, 0 or 1) as argument. It returns a cons
347 of booleans, signifying whether this grob should be transparent and have
348 no extent.
349
350 @node Grob Scheme functions
351 @unnumberedsubsec Grob Scheme functions
352
353 Grob properties can be manipulated from Scheme. In practice, most
354 manipulations are coded in C++ because of tradition.
355
356
357
358 @node Molecules
359 @section Molecules
360
361 @cindex Molecule
362 @cindex Atom
363 @cindex Output description
364
365 The objective of any typesetting system is to put ink on paper in the
366 right places. For LilyPond, this final stage is left to the @TeX{} and
367 the printer subsystem. For lily, the last stage in processing a score is
368 outputting a description of what to put where.  This description roughly
369 looks like
370
371 @example
372         PUT glyph AT (x,y)
373         PUT glyph AT (x,y)
374         PUT glyph AT (x,y) 
375 @end example
376
377 you merely have to look at the tex output of lily to see this.
378 Internally these instructions are encoded in Molecules.@footnote{At some
379 point LilyPond also contained Atom-objects, but they have been replaced
380 by Scheme expressions, making the name outdated.}  A molecule is
381 what-to-print-where information that also contains dimension information
382 (how large is this glyph?).
383
384 Conceptually, Molecules can be constructed from Scheme code, by
385 translating a Molecule and by combining two molecules. In BNF
386 notation:
387
388 @example
389 Molecule  :: COMBINE Molecule Molecule
390            | TRANSLATE Offset Molecule
391            | GLYPH-DESCRIPTION
392            ;
393 @end example
394
395 If you are interested in seeing how this information is stored, you
396 can run with the @code{-f scm} option. The scheme expressions are then
397 dumped in the output file.
398
399 All visible, i.e. non-transparent, grobs have a callback to create a
400 Molecule. The name of the property is @code{molecule-callback}, and its
401 value should be a Scheme function taking one argument (the grob) and
402 returning a Molecule.  Most molecule callbacks are written in C++, but
403 you can also write them in Scheme. An example is provided in
404 @code{input/regression/molecule-hacking.ly}.
405
406  
407