]> git.donarmstrong.com Git - lilypond.git/blob - lily/chord-name.cc
3d786acc8182ae746c968ba96db344292d4f8278
[lilypond.git] / lily / chord-name.cc
1 /*
2   chord-name.cc -- implement Chord_name
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1999--2000 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "chord-name.hh"
10 #include "molecule.hh"
11 #include "paper-def.hh"
12 #include "lookup.hh"
13 #include "score-element.hh"
14 #include "paper-column.hh"
15 #include "line-of-score.hh"
16
17 /*
18   TODO: move text lookup out of Chord_name
19  */
20
21 /*
22   word is roman text or property-styled text:
23    "text"
24    ("text" . property-alist)
25  */
26
27 Molecule
28 Chord_name::ly_word2molecule (Score_element * me, SCM word, Real* x) 
29 {
30   *x = 0;
31
32   SCM options_alist = SCM_EOL;
33   if (gh_pair_p (word))
34     {
35       options_alist = gh_cdr (word);
36       word = gh_car (word);
37     }
38
39   if (gh_string_p (word))
40     {
41       /*
42         UGH. Should read from font metric structure.
43       */
44       Real ex = me->lookup_l ()->text ("", "x",
45                                    me->paper_l ()).extent (Y_AXIS).length ();
46       Real em = me->lookup_l ()->text ("", "m",
47                                    me->paper_l ()).extent (X_AXIS).length ();
48
49       String w = ly_scm2string (word);
50
51       String style;
52       SCM s = scm_assoc (ly_symbol2scm ("style"), options_alist);
53       if (s != SCM_BOOL_F)
54         {
55           style = ly_scm2string (gh_cdr (s));
56         }
57
58       Offset offset;
59       int size = 0;
60       /*
61         urg, `type'
62       */
63       s = scm_assoc (ly_symbol2scm ("type"), options_alist);
64       if (s != SCM_BOOL_F && ly_scm2string (gh_cdr (s)) == "super")
65         {
66           Real super_y = ex / 2;
67           offset = Offset (0, super_y);
68           if (!size)
69             size = -2;
70         }
71
72       s = scm_assoc (ly_symbol2scm ("size"), options_alist);
73       if (s != SCM_BOOL_F)
74         {
75           size = gh_scm2int (gh_cdr (s));
76         }
77
78       s = scm_assoc (ly_symbol2scm ("offset"), options_alist);
79       if (s != SCM_BOOL_F)
80         {
81           // hmm
82           SCM o = gh_cdr (s);
83           if (gh_pair_p (o))
84             offset = Offset (0, gh_scm2double (gh_cdr (o))) * ex;
85           *x = gh_scm2double (gh_car (o)) * em;
86         }
87
88       Molecule mol;
89       s = scm_assoc (ly_symbol2scm ("font"), options_alist);
90       if (s != SCM_BOOL_F && ly_scm2string (gh_cdr (s)) == "feta")
91         mol = me->paper_l ()->lookup_l (size)->afm_find (w);
92       else
93         mol = me->paper_l ()->lookup_l (size)->text (style, w, me->paper_l ());
94
95       mol.translate (offset);
96       return mol;
97     }
98   return Molecule ();
99 }
100
101 /*
102   ;; text: list of word
103   ;; word: string + optional list of property
104   ;; property: align, kern, font (?), size
105  */
106 Molecule
107 Chord_name::ly_text2molecule (Score_element * me, SCM text) 
108 {
109   Molecule mol;
110   if (gh_list_p (text))
111     {
112       while (gh_cdr (text) != SCM_EOL)
113         {
114           Real x;
115           Molecule m = ly_word2molecule (me, gh_car (text), &x);
116           if (!m.empty_b ())
117             mol.add_at_edge (X_AXIS, RIGHT, m, x);
118           text = gh_cdr (text);
119         }
120       text = gh_car (text);
121     }  
122   Real x;
123   Molecule m = ly_word2molecule (me,text, &x);
124   if (!m.empty_b ())
125     mol.add_at_edge (X_AXIS, RIGHT, m, x);
126   return mol;
127 }
128
129 MAKE_SCHEME_CALLBACK (Chord_name, after_line_breaking);
130 SCM
131 Chord_name::after_line_breaking (SCM smob)
132 {
133   Item* me = dynamic_cast<Item*> (unsmob_element (smob));
134   assert (me);
135     
136   SCM s = me->get_elt_property ("begin-of-line-visible");
137   if (to_boolean (s))
138     {
139       if (Paper_column::rank_i (me->column_l ()) -
140           /*
141             hmm, what's my column number in this line?
142             why doesn't this work?
143             me->line_l ()->rank_i_ > 2)
144           */
145           me->line_l ()->spanned_rank_iv ()[LEFT] > 1)
146         me->suicide ();
147     }
148   return SCM_UNSPECIFIED;
149 }
150
151 MAKE_SCHEME_CALLBACK (Chord_name, brew_molecule);
152 SCM
153 Chord_name::brew_molecule (SCM smob) 
154 {
155   Score_element *sc = unsmob_element (smob);
156   SCM style = sc->get_elt_property ("style");
157
158   if (!gh_string_p (style))
159     style = ly_str02scm ("banter");
160
161   SCM inversion = sc-> get_elt_property ("inversion");
162   if (inversion == SCM_EOL)
163     inversion = SCM_BOOL_F;
164
165   SCM bass =  sc->get_elt_property ("bass");
166   if (bass == SCM_EOL)
167     bass = SCM_BOOL_F;
168
169   SCM pitches =  sc->get_elt_property ("pitches");
170   SCM text = scm_eval2 (gh_list (ly_symbol2scm ("chord::user-name"),
171                                 style,
172                                 ly_quote_scm (pitches),
173                                 ly_quote_scm (gh_cons (inversion, bass)),
174                                 SCM_UNDEFINED),
175                         SCM_EOL);
176
177   return ly_text2molecule (sc, text).create_scheme ();
178 }