2 molecule-scheme.cc -- implement Molecule
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "font-metric.hh"
12 LY_DEFINE(ly_molecule_set_extent_x
,"ly:molecule-set-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"
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"
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");
26 Interval iv
= ly_scm2interval (np
);
27 m
->dim_
[Axis (gh_scm2int (axis
))] = iv
;
33 LY_DEFINE(ly_translate_molecule_axis
,"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")
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");
44 q
.translate_axis (gh_scm2double (amount
), Axis (gh_scm2int (axis
)));
46 return q
.smobbed_copy();
49 LY_DEFINE(ly_translate_molecule
,"ly:molecule-translate", 2, 0, 0,
50 (SCM mol
, SCM offset
),
51 "Return a @var{mol}, but translated by @var{offset} (a pair of numbers).")
53 Molecule
* m
= unsmob_molecule (mol
);
54 SCM_ASSERT_TYPE (m
, mol
, SCM_ARG1
, __FUNCTION__
, "molecule");
55 SCM_ASSERT_TYPE (ly_number_pair_p (offset
), offset
, SCM_ARG2
, __FUNCTION__
, "number pair");
56 Offset o
= ly_scm2offset (offset
);
60 return q
.smobbed_copy();
63 LY_DEFINE(ly_molecule_get_extent
,
64 "ly:molecule-get-extent", 2 , 0, 0, (SCM mol
, SCM axis
),
65 "Return a pair of numbers signifying the extent of @var{mol} in "
66 "@var{axis} direction (0 or 1 for x and y axis respectively)."
69 Molecule
*m
= unsmob_molecule (mol
);
70 SCM_ASSERT_TYPE (m
, mol
, SCM_ARG1
, __FUNCTION__
, "molecule");
71 SCM_ASSERT_TYPE (ly_axis_p (axis
), axis
, SCM_ARG2
, __FUNCTION__
, "axis");
73 return ly_interval2scm (m
->extent (Axis (gh_scm2int (axis
))));
77 LY_DEFINE(ly_molecule_combined_at_edge
,
78 "ly:molecule-combine-at-edge",
79 4, 2, 0, (SCM first
, SCM axis
, SCM direction
,
83 "Construct a molecule by putting @var{second} next to "
84 "@var{first}. @var{axis} can be 0 (x-axis) or 1 (y-axis), @var{direction} can be "
85 "-1 (left or down) or 1 (right or up). "
86 "The molecules are juxtaposed with @var{padding} as extra space. If "
87 "this puts the reference points closer than @var{minimum}, they are moved "
88 "by the latter amount.")
91 Molecule
* m1
= unsmob_molecule (first
);
92 Molecule
* m2
= unsmob_molecule (second
);
96 SCM_ASSERT_TYPE(ly_axis_p (axis
), axis
, SCM_ARG3
, __FUNCTION__
, "axis");
97 SCM_ASSERT_TYPE(ly_dir_p (direction
), direction
, SCM_ARG4
, __FUNCTION__
, "dir");
100 if (padding
!= SCM_UNDEFINED
)
102 SCM_ASSERT_TYPE(gh_number_p (padding
), padding
, SCM_ARG5
, __FUNCTION__
, "number");
103 p
= gh_scm2double (padding
);
106 if (minimum
!= SCM_UNDEFINED
)
108 SCM_ASSERT_TYPE(gh_number_p (minimum
), minimum
, SCM_ARG6
, __FUNCTION__
, "number");
109 m
= gh_scm2double (minimum
);
115 result
.add_at_edge (Axis (gh_scm2int (axis
)), Direction (gh_scm2int (direction
)),
118 return result
.smobbed_copy ();
122 FIXME: support variable number of arguments.
125 LY_DEFINE(ly_molecule_add
,
126 "ly:molecule-add", 0, 0, 1, (SCM args
),
127 "Combine molecules. Takes any number of arguments."
130 #define FUNC_NAME __FUNCTION__
131 SCM_VALIDATE_REST_ARGUMENT (args
);
135 while (!SCM_NULLP (args
))
137 Molecule
* m
= unsmob_molecule (gh_car (args
));
140 SCM_ASSERT_TYPE(m
, gh_car (args
), SCM_ARGn
, __FUNCTION__
,
143 result
.add_molecule (*m
);
145 args
= gh_cdr (args
);
148 return result
.smobbed_copy ();
151 LY_DEFINE(ly_make_molecule
,
152 "ly:make-molecule", 3, 0, 0, (SCM expr
, SCM xext
, SCM yext
),
154 "The objective of any typesetting system is to put ink on paper in the \n"
155 "right places. For LilyPond, this final stage is left to the @TeX{} and \n"
156 "the printer subsystem. For lily, the last stage in processing a score is \n"
157 "outputting a description of what to put where. This description roughly \n"
160 " PUT glyph AT (x,y) \n"
161 " PUT glyph AT (x,y) \n"
162 " PUT glyph AT (x,y) \n"
164 "you merely have to look at the tex output of lily to see this. \n"
165 "Internally these instructions are encoded in Molecules.@footnote{At some \n"
166 "point LilyPond also contained Atom-objects, but they have been replaced \n"
167 "by Scheme expressions, making the name outdated.} A molecule is \n"
168 "what-to-print-where information that also contains dimension information \n"
169 "(how large is this glyph?). \n"
171 "Conceptually, Molecules can be constructed from Scheme code, by \n"
172 "translating a Molecule and by combining two molecules. In BNF \n"
176 "Molecule :: COMBINE Molecule Molecule \n"
177 " | TRANSLATE Offset Molecule \n"
178 " | GLYPH-DESCRIPTION \n"
182 "If you are interested in seeing how this information is stored, you \n"
183 "can run with the @code{-f scm} option. The scheme expressions are then \n"
184 "dumped in the output file.")
186 SCM_ASSERT_TYPE (ly_number_pair_p (xext
), xext
, SCM_ARG2
, __FUNCTION__
, "number pair");
187 SCM_ASSERT_TYPE (ly_number_pair_p (yext
), yext
, SCM_ARG3
, __FUNCTION__
, "number pair");
189 Box
b (ly_scm2interval (xext
), ly_scm2interval(yext
));
190 Molecule
m (b
, expr
);
191 return m
.smobbed_copy ();
196 fontify_atom (Font_metric
const * met
, SCM f
)
201 return scm_list_n (ly_symbol2scm ("fontify"),
202 ly_quote_scm (met
->description_
), f
, SCM_UNDEFINED
);
205 LY_DEFINE(ly_fontify_atom
,"ly:fontify-atom", 2, 0, 0,
207 "Add a font selection command for the font metric @var{met} to @var{f}.")
209 SCM_ASSERT_TYPE(unsmob_metrics (met
), met
, SCM_ARG1
, __FUNCTION__
, "font metric");
211 return fontify_atom (unsmob_metrics (met
), f
);
213 LY_DEFINE(ly_align_to_x
,"ly:molecule-align-to!", 3, 0, 0, (SCM mol
, SCM axis
, SCM dir
),
215 "Align @var{mol} using its own extents. @var{dir} is a number -1, 1 are "
216 " left and right respectively. Other values are interpolated (so 0 means "
219 SCM_ASSERT_TYPE(unsmob_molecule (mol
), mol
, SCM_ARG1
, __FUNCTION__
, "molecule");
220 SCM_ASSERT_TYPE(ly_axis_p (axis
), axis
, SCM_ARG2
, __FUNCTION__
, "axis");
221 SCM_ASSERT_TYPE(gh_number_p (dir
), dir
, SCM_ARG3
, __FUNCTION__
, "number");
223 unsmob_molecule (mol
)->align_to ((Axis
)gh_scm2int (axis
),
224 gh_scm2double (dir
));
226 return SCM_UNDEFINED
;