]> git.donarmstrong.com Git - lilypond.git/blob - lily/molecule-scheme.cc
2002-12-06 Han-Wen Nienhuys <hanwen@cs.uu.nl>
[lilypond.git] / lily / molecule-scheme.cc
1 /*
2   molecule-scheme.cc -- implement Molecule
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "molecule.hh"
10 #include "font-metric.hh"
11
12 LY_DEFINE(ly_set_molecule_extent_x,"ly:set-molecule-extent!", 3 , 0, 0, 
13           (SCM mol, SCM axis, SCM np),
14           "Set the extent (@var{extent} must be a pair of numbers) of @var{mol} in \n"
15 "@var{axis} direction (0 or 1 for x- and y-axis respectively).\n"
16 "\n"
17 "Note that an extent @code{(A . B)} is an interval and hence @code{A} is\n"
18 "smaller than @code{B}, and is often negative.\n"
19 )
20 {
21   Molecule* m = unsmob_molecule (mol);
22   SCM_ASSERT_TYPE (m, mol, SCM_ARG1, __FUNCTION__, "molecule");
23   SCM_ASSERT_TYPE (ly_axis_p (axis), axis, SCM_ARG2, __FUNCTION__, "axis");
24   SCM_ASSERT_TYPE (ly_number_pair_p (np), np, SCM_ARG3, __FUNCTION__, "number pair");
25
26   Interval iv = ly_scm2interval (np);
27   m->dim_[Axis (gh_scm2int (axis))] = iv;
28
29   return SCM_UNDEFINED;
30 }
31
32
33 LY_DEFINE(ly_translate_molecule,"ly:molecule-translate-axis", 3, 0, 0, 
34           (SCM mol, SCM amount, SCM axis),
35           "Return a @var{mol}, but translated by @var{amount} in @var{axis} direction")
36 {
37   Molecule* m = unsmob_molecule (mol);
38   SCM_ASSERT_TYPE (m, mol, SCM_ARG1, __FUNCTION__, "molecule");
39   SCM_ASSERT_TYPE (gh_number_p (amount), amount, SCM_ARG2, __FUNCTION__, "number pair");
40   SCM_ASSERT_TYPE (ly_axis_p (axis), axis, SCM_ARG3, __FUNCTION__, "axis");
41
42
43   Molecule q (*m);
44   q.translate_axis (gh_scm2double (amount), Axis (gh_scm2int (axis)));
45
46   return q.smobbed_copy();
47 }
48
49 LY_DEFINE(ly_get_molecule_extent,
50           "ly:get-molecule-extent", 2 , 0, 0,  (SCM mol, SCM axis),
51           "Return a pair of numbers signifying the extent of @var{mol} in "
52 "@var{axis} direction (0 or 1 for x and y axis respectively)."
53 )
54 {
55   Molecule *m = unsmob_molecule (mol);
56   SCM_ASSERT_TYPE (m, mol, SCM_ARG1, __FUNCTION__, "molecule");
57   SCM_ASSERT_TYPE (ly_axis_p (axis), axis, SCM_ARG2, __FUNCTION__, "axis");
58  
59   return ly_interval2scm (m->extent (Axis (gh_scm2int (axis))));
60 }
61
62
63 LY_DEFINE(ly_molecule_combined_at_edge,
64           "ly:combine-molecule-at-edge",
65           4, 2, 0,  (SCM first, SCM axis, SCM direction,
66                      SCM second,
67                      SCM padding,
68                      SCM minimum),
69           "Construct a molecule by putting @var{second} next to "
70 "@var{first}. @var{axis} can be 0 (x-axis) or 1 (y-axis), @var{direction} can be "
71 "-1 (left or down) or 1 (right or up). "
72 "The molecules are juxtaposed with  @var{padding} as extra space. If "
73 "this puts the reference points closer than @var{minimum}, they are moved "
74 "by the latter amount.")
75
76 {
77   Molecule * m1 = unsmob_molecule (first);
78   Molecule * m2 = unsmob_molecule (second);
79   Molecule result;
80
81
82   SCM_ASSERT_TYPE(ly_axis_p (axis), axis, SCM_ARG3, __FUNCTION__, "axis");
83   SCM_ASSERT_TYPE(ly_dir_p (direction), direction, SCM_ARG4, __FUNCTION__, "dir");
84
85   Real p = 0.0;
86   if (padding != SCM_UNDEFINED)
87     {
88       SCM_ASSERT_TYPE(gh_number_p (padding), padding, SCM_ARG5, __FUNCTION__, "number");
89       p = gh_scm2double (padding);
90     }
91   Real m =0.0;
92   if (minimum != SCM_UNDEFINED)
93     {
94       SCM_ASSERT_TYPE(gh_number_p (minimum), minimum, SCM_ARG6, __FUNCTION__, "number");
95       m = gh_scm2double (minimum);
96     }
97   
98   if (m1)
99     result = *m1;
100   if (m2)
101     result.add_at_edge (Axis (gh_scm2int (axis)), Direction (gh_scm2int (direction)),
102                         *m2, p, m);
103
104   return result.smobbed_copy ();
105 }
106
107 /*
108   FIXME: support variable number of arguments "
109  */
110 LY_DEFINE(ly_add_molecule , 
111           "ly:add-molecule", 2, 0, 0, (SCM first, SCM second),
112           "Combine two molecules."
113           )
114 {
115   Molecule * m1 = unsmob_molecule (first);
116   Molecule * m2 = unsmob_molecule (second);
117   Molecule result;
118
119
120   if (m1)
121     result = *m1;
122   if (m2)
123     result.add_molecule (*m2);
124
125   return result.smobbed_copy ();
126 }
127
128 LY_DEFINE(ly_make_molecule,
129           "ly:make-molecule", 3, 0, 0,  (SCM expr, SCM xext, SCM yext),
130           " \n"
131 "The objective of any typesetting system is to put ink on paper in the \n"
132 "right places. For LilyPond, this final stage is left to the @TeX{} and \n"
133 "the printer subsystem. For lily, the last stage in processing a score is \n"
134 "outputting a description of what to put where.  This description roughly \n"
135 "looks like \n"
136 "@example \n"
137 "        PUT glyph AT (x,y) \n"
138 "        PUT glyph AT (x,y) \n"
139 "        PUT glyph AT (x,y)  \n"
140 "@end example \n"
141 "you merely have to look at the tex output of lily to see this. \n"
142 "Internally these instructions are encoded in Molecules.@footnote{At some \n"
143 "point LilyPond also contained Atom-objects, but they have been replaced \n"
144 "by Scheme expressions, making the name outdated.}  A molecule is \n"
145 "what-to-print-where information that also contains dimension information \n"
146 "(how large is this glyph?). \n"
147 " \n"
148 "Conceptually, Molecules can be constructed from Scheme code, by \n"
149 "translating a Molecule and by combining two molecules. In BNF \n"
150 "notation: \n"
151 " \n"
152 "@example \n"
153 "Molecule  :: COMBINE Molecule Molecule \n"
154 "           | TRANSLATE Offset Molecule \n"
155 "           | GLYPH-DESCRIPTION \n"
156 "           ; \n"
157 "@end example \n"
158 " \n"
159 "If you are interested in seeing how this information is stored, you \n"
160 "can run with the @code{-f scm} option. The scheme expressions are then \n"
161 "dumped in the output file.")
162 {
163   SCM_ASSERT_TYPE (ly_number_pair_p (xext), xext, SCM_ARG2, __FUNCTION__, "number pair");
164   SCM_ASSERT_TYPE (ly_number_pair_p (yext), yext, SCM_ARG3, __FUNCTION__, "number pair");  
165
166   Box b (ly_scm2interval (xext), ly_scm2interval(yext));
167   Molecule m (b, expr);
168   return m.smobbed_copy ();
169 }
170
171
172 SCM
173 fontify_atom (Font_metric const * met, SCM f)
174 {
175   if (f == SCM_EOL)
176     return f;
177   else
178     return  scm_list_n (ly_symbol2scm ("fontify"),
179                         ly_quote_scm (met->description_), f, SCM_UNDEFINED);
180 }
181
182 LY_DEFINE(ly_fontify_atom,"ly:fontify-atom", 2, 0, 0, 
183           (SCM met, SCM f),
184           "Add a font selection command for the font metric @var{met} to @var{f}.")
185 {
186   SCM_ASSERT_TYPE(unsmob_metrics (met), met, SCM_ARG1, __FUNCTION__, "font metric");
187
188   return fontify_atom (unsmob_metrics (met), f);
189 }
190 LY_DEFINE(ly_align_to_x,"ly:align-to!", 3, 0, 0,  (SCM mol, SCM axis, SCM dir),
191           "Align @var{mol} using its own extents.")
192 {
193   SCM_ASSERT_TYPE(unsmob_molecule (mol), mol, SCM_ARG1, __FUNCTION__, "molecule");
194   SCM_ASSERT_TYPE(ly_axis_p (axis), axis, SCM_ARG2, __FUNCTION__, "axis");
195   SCM_ASSERT_TYPE(ly_dir_p (dir), dir, SCM_ARG3, __FUNCTION__, "dir");
196
197   unsmob_molecule (mol)->align_to ((Axis)gh_scm2int (axis), Direction (gh_scm2int (dir)));
198
199   return SCM_UNDEFINED;
200 }