]> git.donarmstrong.com Git - lilypond.git/blob - lily/ligature-bracket.cc
eb190aca44944725d6412d419192165628c84381
[lilypond.git] / lily / ligature-bracket.cc
1 /*
2   ligature-bracket.cc -- implement Ligature_bracket
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2002 Juergen Reuter <reuter@ipd.uka.de>
7 */
8
9 #include "ligature-bracket.hh"
10 #include "item.hh"
11 #include "paper-def.hh"
12 #include "spanner.hh"
13 #include "staff-symbol-referencer.hh"
14 #include "lookup.hh"
15 #include "box.hh"
16
17 static Molecule
18 brew_edge (Direction dir, Real thickness, Real width, Real height,
19            Real blotdiameter)
20 {
21   Molecule hline = Lookup::roundfilledbox (Box (Interval (0, width),
22                                                 Interval (0, thickness)),
23                                            blotdiameter);
24   hline.translate_axis (height - thickness, Y_AXIS);
25
26   Molecule vline = Lookup::roundfilledbox (Box (Interval (0, thickness),
27                                                 Interval (0, height)),
28                                            blotdiameter);
29   if (dir == RIGHT)
30     {
31       vline.translate_axis (width - thickness, X_AXIS);
32     }
33
34   Molecule edge = Molecule ();
35   edge.add_molecule (hline);
36   edge.add_molecule (vline);
37   return edge;
38 }
39
40 MAKE_SCHEME_CALLBACK (Ligature_bracket, brew_molecule, 1);
41 SCM
42 Ligature_bracket::brew_molecule (SCM smob)
43 {
44   Grob *me = unsmob_grob (smob);
45   Spanner *spanner = dynamic_cast<Spanner*> (me);
46   Real blotdiameter = me->paper_l ()->get_var ("blotdiameter");
47   Real staff_space = Staff_symbol_referencer::staff_space (me);
48
49   Real thickness = me->paper_l ()->get_var ("linethickness");  
50   SCM grob_thickness = me->get_grob_property ("thickness");
51   if (gh_number_p (grob_thickness))
52     thickness *= gh_scm2double (grob_thickness);
53
54   SCM edge_width_scm = me->get_grob_property ("width");
55   Real edge_width;
56   if (gh_number_p (edge_width_scm))
57     {
58       edge_width = gh_scm2double (edge_width_scm);
59     }
60   else
61     {
62       edge_width = 0.75;
63     }
64   edge_width *= staff_space;
65
66   SCM edge_height_scm = me->get_grob_property ("height");
67   Real edge_height;
68   if (gh_number_p (edge_height_scm))
69     {
70       edge_height = gh_scm2double (edge_height_scm);
71     }
72   else
73     {
74       edge_height = 0.5;
75     }
76   edge_height *= staff_space;
77
78   Item* left_bound = spanner->get_bound (LEFT);
79   Item* right_bound = spanner->get_bound (RIGHT);
80
81   Molecule bracket = Molecule ();
82
83   Real y_min_offs =
84     0.5 * Staff_symbol_referencer::line_count (me) * staff_space;
85   Real y_left_offs = y_min_offs;
86   Real y_right_offs = y_min_offs;
87
88   Real left_bound_left_extent = 0;
89
90   if (left_bound)
91     {
92       Molecule left_edge =
93         brew_edge (LEFT, thickness, edge_width, edge_height, blotdiameter);
94       Grob *left_common_x = me->common_refpoint (left_bound, X_AXIS);
95       left_bound_left_extent =
96         left_bound->extent (left_common_x, X_AXIS)[LEFT];
97       left_edge.translate_axis (left_bound_left_extent, X_AXIS);
98       bracket.add_molecule (left_edge);
99       Grob *left_common_y = me->common_refpoint (left_bound, Y_AXIS);
100       y_left_offs =
101         max(y_left_offs, left_bound->extent (left_common_y, Y_AXIS)[UP]);
102     }
103   else
104     {
105       me->warning (_ ("no left bound"));
106     }
107
108   if (right_bound)
109     {
110       Molecule right_edge =
111         brew_edge (RIGHT, thickness, edge_width, edge_height, blotdiameter);
112       Grob *staff_symbol = Staff_symbol_referencer::staff_symbol_l (me);
113       Grob *right_common_bound_x =
114         right_bound->common_refpoint (staff_symbol, X_AXIS);
115
116       Real left_offs = 0;
117       if (left_bound)
118         {
119           Grob *left_common_bound_x =
120             left_bound->common_refpoint (staff_symbol, X_AXIS);
121           left_offs = left_bound->extent (left_common_bound_x, X_AXIS)[LEFT];
122         }
123
124       Real right_offs =
125         right_bound->extent (right_common_bound_x, X_AXIS)[RIGHT];
126
127       right_edge.translate_axis (+ right_offs
128                                  - left_offs
129                                  + left_bound_left_extent
130                                  - edge_width,
131                                  X_AXIS);
132       bracket.add_molecule (right_edge);
133       Grob *right_common_y = me->common_refpoint (right_bound, Y_AXIS);
134       y_right_offs =
135         max(y_right_offs, right_bound->extent (right_common_y, Y_AXIS)[UP]);
136     }
137   else
138     {
139       me->warning (_ ("no left bound"));
140     }
141
142   bracket.translate_axis (max (y_left_offs, y_right_offs), Y_AXIS);
143
144   return bracket.smobbed_copy ();
145 }
146
147 ADD_INTERFACE(Ligature_bracket, "ligature-bracket-interface",
148               "A bracket indicating a ligature in the original edition",
149               "width thickness height");