]> git.donarmstrong.com Git - lilypond.git/blob - lily/lyric-extender.cc
* lily/lily-guile.cc (robust_scm2double): new function. Use throughout.
[lilypond.git] / lily / lyric-extender.cc
1 /*
2   lyric-extender.cc -- implement Lyric_extender
3   source file of the GNU LilyPond music typesetter
4
5   (c)  1998--2003 Jan Nieuwenhuizen <janneke@gnu.org>
6   Han-Wen Nienhuys
7 */
8
9 #include <math.h>
10
11 #include "box.hh"
12 #include "warn.hh"
13 #include "lookup.hh"
14 #include "molecule.hh"
15 #include "paper-column.hh"
16 #include "paper-def.hh"
17 #include "lyric-extender.hh"
18 #include "note-head.hh"
19 #include "group-interface.hh"
20
21 MAKE_SCHEME_CALLBACK (Lyric_extender,brew_molecule,1)
22 SCM 
23 Lyric_extender::brew_molecule (SCM smob) 
24 {
25   Spanner *me = unsmob_spanner (smob);
26   Item *l = me->get_bound (LEFT);
27   Item *r = me->get_bound (RIGHT);
28   Grob *common = l->common_refpoint (r, X_AXIS);
29   
30
31   Real sl = me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness"));  
32
33   Link_array<Grob> heads (Pointer_group_interface__extract_grobs (me, (Grob*)0,
34                                                                   "heads"));
35
36   if (!heads.size () && r->break_status_dir () == CENTER)
37     return SCM_EOL;
38
39   common = common_refpoint_of_array (heads, common, X_AXIS);
40   
41   Real left_point = 0.0;
42   if (l->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")))
43     left_point = l->extent (common, X_AXIS)[RIGHT];
44   else
45     left_point = heads[0]->extent (common, X_AXIS)[LEFT];
46
47   if (isinf (left_point))
48     return SCM_EOL;
49
50   /*
51     It seems that short extenders are even lengthened to go past the note head,  but
52     haven't found a pattern in it yet. --hwn  1/1/04
53     
54    */
55   SCM minlen =  me->get_grob_property ("minimum-length");
56   Real right_point
57     = left_point + (robust_scm2double  (minlen,0));
58
59   if (r->break_status_dir ())
60     right_point = infinity_f;
61   else
62     right_point = right_point >? heads.top ()->extent (common, X_AXIS)[RIGHT];
63   
64   Real h = sl * robust_scm2double (me->get_grob_property ("thickness"), 0);
65   Real pad = 2* h;
66   right_point = right_point <? (r->extent (common, X_AXIS)[LEFT] - pad);
67
68   if (isinf (right_point))
69     return SCM_EOL;
70   
71
72   left_point += pad;
73
74   Real w = right_point - left_point;
75
76   if (w < 0)
77     return SCM_EOL;
78   
79   Molecule  mol (Lookup::round_filled_box (Box (Interval (0,w), Interval (0,h)),
80                                            0.8 * h));
81   mol.translate_axis (left_point - me->relative_coordinate (common, X_AXIS), X_AXIS);
82   return mol.smobbed_copy ();
83 }
84
85
86 ADD_INTERFACE (Lyric_extender,"lyric-extender-interface",
87   "The extender is a simple line at the baseline of the lyric "
88   " that helps show the length of a melissima (tied/slurred note).",
89   "thickness heads");