]> git.donarmstrong.com Git - lilypond.git/blob - lily/piano-pedal-bracket.cc
* mf/GNUmakefile: always trace pfa fonts.
[lilypond.git] / lily / piano-pedal-bracket.cc
1 /*   
2   piano-pedal-bracket.cc --  implement  Piano_pedal_bracket
3
4 source file of the GNU LilyPond music typesetter
5
6 (c) 2003 Han-Wen Nienhuys <hanwen@xs4all.nl>
7
8 based on smouldering remains by
9
10    Chris Jackson <chris@fluffhouse.org.uk>
11
12
13 */
14 /* 
15    Piano pedal brackets are a special case of a text spanner.
16    Pedal up-down (restart) indicated by the angled right and left edges 
17    of consecutive pedals touching exactly to form an __/\__
18
19 */
20
21
22 /*
23   TODO: this should be moved somewhere else (?).
24
25   Perhaps make separate function for pedal-bracket.
26  */
27 #include "molecule.hh"
28 #include "spanner.hh"
29 #include "item.hh"
30 #include "paper-def.hh"
31
32 struct Piano_pedal_bracket
33 {
34   DECLARE_SCHEME_CALLBACK(after_line_breaking,(SCM));
35   static bool has_interface (Grob*);
36 };
37
38 ADD_INTERFACE (Piano_pedal_bracket,"piano-pedal-bracket-interface",
39                "",
40                "pedal-text");
41
42 MAKE_SCHEME_CALLBACK(Piano_pedal_bracket,after_line_breaking,1);
43 SCM
44 Piano_pedal_bracket::after_line_breaking (SCM smob)
45 {
46   Spanner *me = dynamic_cast<Spanner*> (unsmob_grob (smob));
47
48   Drul_array<bool> broken;
49   Drul_array<Real> height(0,0), shorten(0,0);
50
51   SCM eh = me->get_grob_property ("edge-height");
52   SCM sp = me->get_grob_property ("shorten-pair");
53   
54   Direction d = LEFT;
55
56   do
57     {
58       Item *b = me->get_bound (d);
59       broken[d] = b->break_status_dir () != CENTER;
60
61       if (!broken[d] && (is_number_pair (eh)))
62         height[d] += gh_scm2double (index_get_cell (eh, d));
63       if (is_number_pair (sp))
64         shorten[d] +=  gh_scm2double (index_get_cell (sp, d));
65     }
66   while (flip (&d) != LEFT);
67   
68   /* For 'Mixed' style pedals, i.e.  a bracket preceded by text:  Ped._____|
69    need to shorten by the extent of the text grob
70
71
72    Urg. - why not hang bracket between text items? --hwn
73   */
74   if (Grob *textbit = unsmob_grob (me->get_grob_property("pedal-text")))
75     {
76       height[LEFT] = 0;
77       SCM pa = me->get_grob_property ("if-text-padding"); // UGH.
78       Real padding =0.;
79       if (gh_number_p (pa))
80         padding = gh_scm2double (pa);
81           
82       shorten[LEFT] += padding + textbit->extent (textbit, X_AXIS)[RIGHT];
83     }
84   
85   if (broken[LEFT])
86     {
87       shorten[LEFT]  -=  me->get_broken_left_end_align () ;
88     }
89
90   // Also shorten so that it ends just before the spanned note.
91   Grob  *rb = me->get_bound (RIGHT);
92   shorten[RIGHT]  += rb->extent (rb, X_AXIS)[RIGHT];
93     
94   me->set_grob_property ("edge-height", ly_interval2scm (height));
95   me->set_grob_property ("shorten-pair", ly_interval2scm (shorten));
96
97   return SCM_UNSPECIFIED;
98 }
99