]> git.donarmstrong.com Git - lilypond.git/blob - lily/accidental.cc
* lily/lily-guile.cc (type_check_assignment): if
[lilypond.git] / lily / accidental.cc
1 #include "font-interface.hh"
2 #include "item.hh"
3 #include "molecule.hh"
4 #include "accidental-interface.hh"
5
6 /*
7   TODO: insert support for smaller cautionaries, tie-break-reminders.
8   Either here or in new-accidental-engraver.
9
10   'accidentals should go, for a single 'accidental property -- see
11   accidental-placement.cc
12
13 */
14
15
16 Molecule
17 parenthesize (Grob*me, Molecule m)
18 {
19   Molecule open = Font_interface::get_default_font (me)->find_by_name (String ("accidentals-leftparen"));
20   Molecule close = Font_interface::get_default_font (me)->find_by_name (String ("accidentals-rightparen"));
21   m.add_at_edge (X_AXIS, LEFT, Molecule (open), 0);
22   m.add_at_edge (X_AXIS, RIGHT, Molecule (close), 0);
23
24   return m;
25 }
26
27
28 MAKE_SCHEME_CALLBACK (Accidental_interface,after_line_breaking,1);
29 SCM
30 Accidental_interface::after_line_breaking (SCM smob)
31 {
32   Grob *me  = unsmob_grob (smob);
33   Grob *tie = unsmob_grob (me->get_grob_property ("tie"));
34
35   if (tie && !tie->original_)
36     {
37       me->suicide ();
38     }
39   return SCM_UNSPECIFIED;
40 }
41
42 Array<Box>
43 Accidental_interface::accurate_boxes (Grob *a,Grob**common)
44 {
45   Box b;
46   b[X_AXIS] = a->extent (a, X_AXIS);
47   b[Y_AXIS] = a->extent (a, Y_AXIS);
48
49   Array<Box> boxes;
50   
51   bool parens = false;
52   if (to_boolean (a->get_grob_property ("cautionary")))
53     {
54       SCM cstyle = a->get_grob_property ("cautionary-style");
55       parens = gh_equal_p (cstyle, ly_symbol2scm ("parentheses"));
56
57     }
58
59   SCM accs = a->get_grob_property ("accidentals");
60   SCM scm_style = a->get_grob_property ("style");
61   if (!gh_symbol_p (scm_style)
62       && !parens
63       && scm_ilength (accs) == 1)
64     {
65       if (gh_scm2int (gh_car (accs)) == -1)
66         {
67           Box stem = b;
68           Box bulb = b;
69
70           /*
71             we could make the stem thinner, but that places the flats
72             really close.
73           */
74           stem[X_AXIS][RIGHT] *= .5;
75           bulb[Y_AXIS][UP] *= .35;
76
77           boxes.push (bulb);
78           boxes.push (stem);
79         }
80       /*
81         TODO: add support for natural, double flat.
82        */
83     }
84
85   if (!boxes.size())
86     boxes.push (b);
87
88   Offset o (a->relative_coordinate (common[X_AXIS],  X_AXIS),
89             a->relative_coordinate (common[Y_AXIS],  Y_AXIS));
90   for(int i = boxes.size(); i--;)
91     {
92       boxes[i].translate(o);
93     }
94   
95   return boxes;
96 }
97
98 MAKE_SCHEME_CALLBACK (Accidental_interface,brew_molecule,1);
99 SCM
100 Accidental_interface::brew_molecule (SCM smob)
101 {
102   Grob *me = unsmob_grob (smob);
103   bool smaller = false;
104   bool parens = false;
105   
106   bool caut  = to_boolean (me->get_grob_property ("cautionary"));
107   if (caut)
108     {
109       SCM cstyle = me->get_grob_property ("cautionary-style");
110       parens = gh_equal_p (cstyle, ly_symbol2scm ("parentheses"));
111       smaller = gh_equal_p (cstyle, ly_symbol2scm ("smaller"));
112     }
113   
114   SCM scm_style = me->get_grob_property ("style");
115   String style;
116   if (gh_symbol_p (scm_style))
117     {
118       style = ly_scm2string (scm_symbol_to_string (scm_style));
119     }
120   else
121     {
122       /*
123         preferably no name for the default style.
124        */
125       style = "";
126     }
127
128
129   Font_metric *fm = 0;
130   if (smaller)
131     {
132       SCM ac = Font_interface::font_alist_chain (me);
133       ac = gh_cons (gh_cons (gh_cons
134                              (ly_symbol2scm ("font-relative-size"),
135                               scm_int2num (-1)), SCM_EOL),
136                     ac);
137       fm = Font_interface::get_font (me, ac);
138     }
139   else
140     fm = Font_interface::get_default_font (me);
141
142   Molecule mol;
143   for (SCM s = me->get_grob_property ("accidentals");
144        gh_pair_p (s);  s= gh_cdr (s))
145     {
146       SCM entry  = gh_car (s);
147       
148       
149       Molecule acc (fm->find_by_name (String ("accidentals-") +
150                                       style +
151                                       to_string (gh_scm2int(entry))));
152       
153       mol.add_at_edge (X_AXIS,  RIGHT, acc, 0.1);
154     }
155
156   if (parens)
157     mol = parenthesize (me, mol); 
158
159   return mol.smobbed_copy();
160 }
161
162
163
164 ADD_INTERFACE (Accidental_interface, "accidental-interface",
165               "a single accidental",
166                "cautionary cautionary-style style tie accidentals");