X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fmolecule.cc;h=127850d1238e12e2c05b3a571e35f7e8468dfc1b;hb=1403a2c3b4a03ee78be253ac4c4f206b7a3b05db;hp=5e124b2e90c3147a1bc036e9591e13b9407b1439;hpb=75f8a001fe30f30fa2d32a961218d0f1cdbeeb7e;p=lilypond.git diff --git a/lily/molecule.cc b/lily/molecule.cc index 5e124b2e90..127850d123 100644 --- a/lily/molecule.cc +++ b/lily/molecule.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1997--2001 Han-Wen Nienhuys + (c) 1997--2002 Han-Wen Nienhuys */ #include @@ -14,7 +14,7 @@ #include "interval.hh" #include "string.hh" #include "molecule.hh" -#include "debug.hh" +#include "warn.hh" #include "ly-smobs.icc" @@ -52,7 +52,7 @@ Molecule::translate (Offset o) Axis a = X_AXIS; while (a < NO_AXES) { - if (abs (o[a]) > 30 CM + if (abs (o[a]) > 100 CM || isinf (o[a]) || isnan (o[a])) { programming_error ("Improbable offset for translation: setting to zero"); @@ -107,6 +107,9 @@ Molecule::set_empty (bool e) void Molecule::align_to (Axis a, Direction d) { + if (empty_b()) + return ; + Interval i (extent (a)); Real r = (d == CENTER) ? i.center () : i[d]; translate_axis (-r, a); @@ -132,100 +135,174 @@ Molecule::add_at_edge (Axis a, Direction d, Molecule const &m, Real padding) add_molecule (toadd); } -/* ly_? Thought we had the ly_ prefix for wrapping/adding to gh_ */ -SCM -Molecule::ly_set_molecule_extent_x (SCM mol, SCM axis, SCM np) +LY_DEFINE(ly_set_molecule_extent_x,"ly:set-molecule-extent!", 3 , 0, 0, + (SCM mol, SCM axis, SCM np), + "Set the extent (@var{extent} must be a pair of numbers) of @var{mol} in +@var{axis} direction (0 or 1 for x- and y-axis respectively). + +Note that an extent @code{(A . B)} is an interval and hence @code{A} is +smaller than @code{B}, and is often negative. +5") { Molecule* m = unsmob_molecule (mol); - if (m && ly_axis_p (axis) && ly_number_pair_p (np)) - { - Interval iv = ly_scm2interval (np); - m->dim_[Axis (gh_scm2int (axis))] = ly_scm2interval (np); - } - else - warning ("ly-set-molecule-extent!: invalid arguments"); + SCM_ASSERT_TYPE (m, mol, SCM_ARG1, __FUNCTION__, "molecule"); + SCM_ASSERT_TYPE (ly_axis_p (axis), axis, SCM_ARG2, __FUNCTION__, "axis"); + SCM_ASSERT_TYPE (ly_number_pair_p (np), np, SCM_ARG3, __FUNCTION__, "number pair"); + + Interval iv = ly_scm2interval (np); + m->dim_[Axis (gh_scm2int (axis))] = iv; + return SCM_UNDEFINED; } -SCM -Molecule::ly_get_molecule_extent (SCM mol, SCM axis) +LY_DEFINE(ly_get_molecule_extent, + "ly:get-molecule-extent", 2 , 0, 0, (SCM mol, SCM axis), + "Return a pair of numbers signifying the extent of @var{mol} in +@var{axis} direction (0 or 1 for x and y axis respectively). +") { Molecule *m = unsmob_molecule (mol); + SCM_ASSERT_TYPE (m, mol, SCM_ARG1, __FUNCTION__, "molecule"); + SCM_ASSERT_TYPE (ly_axis_p (axis), axis, SCM_ARG2, __FUNCTION__, "axis"); - if (!m || !ly_axis_p (axis)) - { - warning ("ly-get-molecule-extent: invalid arguments"); - return ly_interval2scm (Interval (0,0)); - } - return ly_interval2scm (m->extent (Axis (gh_scm2int (axis)))); } -SCM -Molecule::ly_molecule_combined_at_edge (SCM first, SCM axis, SCM direction, - SCM second, SCM padding) +LY_DEFINE(ly_molecule_combined_at_edge, + "ly:combine-molecule-at-edge", + 5 , 0, 0, (SCM first, SCM axis, SCM direction, + SCM second, SCM padding), + "Construct a molecule by putting @var{second} next to +@var{first}. @var{axis} can be 0 (x-axis) or 1 (y-axis), @var{direction} can be +-1 (left or down) or 1 (right or up). @var{padding} specifies extra +space to add in between measured in global staff space.") { Molecule * m1 = unsmob_molecule (first); Molecule * m2 = unsmob_molecule (second); Molecule result; - - if (!m1 || !m2 || !isdir_b (direction) || !ly_axis_p (axis) || !gh_number_p (padding)) - { - warning ("ly-combine-molecule-at-edge: invalid arguments"); - Molecule r; - return r.smobbed_copy (); - } - result = *m1; - result.add_at_edge (Axis (gh_scm2int (axis)), Direction (gh_scm2int (direction)), - *m2, gh_scm2double (padding)); + SCM_ASSERT_TYPE(ly_axis_p (axis), axis, SCM_ARG2, __FUNCTION__, "axis"); + SCM_ASSERT_TYPE(ly_dir_p (direction), direction, SCM_ARG3, __FUNCTION__, "dir"); + SCM_ASSERT_TYPE(gh_number_p (padding), padding, SCM_ARG4, __FUNCTION__, "number"); + + if (m1) + result = *m1; + if (m2) + result.add_at_edge (Axis (gh_scm2int (axis)), Direction (gh_scm2int (direction)), + *m2, gh_scm2double (padding)); return result.smobbed_copy (); } +/* + FIXME: support variable number of arguments " + */ +LY_DEFINE(ly_add_molecule , + "ly:add-molecule", 2, 0,0,(SCM first, SCM second), + "Combine two molecules." + ) +{ + Molecule * m1 = unsmob_molecule (first); + Molecule * m2 = unsmob_molecule (second); + Molecule result; + -SCM -make_molecule (SCM expr, SCM xext, SCM yext) + if (m1) + result = *m1; + if (m2) + result.add_molecule (*m2); + + return result.smobbed_copy (); +} + +LY_DEFINE(ly_make_molecule, + "ly:make-molecule", 3, 0, 0, (SCM expr, SCM xext, SCM yext), + " +The objective of any typesetting system is to put ink on paper in the +right places. For LilyPond, this final stage is left to the @TeX{} and +the printer subsystem. For lily, the last stage in processing a score is +outputting a description of what to put where. This description roughly +looks like +@example + PUT glyph AT (x,y) + PUT glyph AT (x,y) + PUT glyph AT (x,y) +@end example +you merely have to look at the tex output of lily to see this. +Internally these instructions are encoded in Molecules.@footnote{At some +point LilyPond also contained Atom-objects, but they have been replaced +by Scheme expressions, making the name outdated.} A molecule is +what-to-print-where information that also contains dimension information +(how large is this glyph?). + +Conceptually, Molecules can be constructed from Scheme code, by +translating a Molecule and by combining two molecules. In BNF +notation: + +@example +Molecule :: COMBINE Molecule Molecule + | TRANSLATE Offset Molecule + | GLYPH-DESCRIPTION + ; +@end example + +If you are interested in seeing how this information is stored, you +can run with the @code{-f scm} option. The scheme expressions are then +dumped in the output file.") { - /* - TODO: typechecking. - */ + SCM_ASSERT_TYPE (ly_number_pair_p (xext), xext, SCM_ARG2, __FUNCTION__, "number pair"); + SCM_ASSERT_TYPE (ly_number_pair_p (yext), yext, SCM_ARG3, __FUNCTION__, "number pair"); + Box b (ly_scm2interval (xext), ly_scm2interval(yext)); Molecule m (b, expr); return m.smobbed_copy (); } +SCM +fontify_atom (Font_metric const * met, SCM f) +{ + if (f == SCM_EOL) + return f; + else + return scm_list_n (ly_symbol2scm ("fontify"), + ly_quote_scm (met->description_), f, SCM_UNDEFINED); +} + +LY_DEFINE(ly_fontify_atom,"ly:fontify-atom", 2, 0, 0, + (SCM met, SCM f), + "Add a font selection command for the font metric @var{met} to @var{f}.") +{ + SCM_ASSERT_TYPE(unsmob_metrics (met), met, SCM_ARG1, __FUNCTION__, "font metric"); -static void -molecule_init () + return fontify_atom (unsmob_metrics (met), f); +} +LY_DEFINE(ly_align_to_x,"ly:align-to!", 3, 0, 0, (SCM mol, SCM axis, SCM dir), + "Align @var{mol} using its own extents.") { - scm_c_define_gsubr ("ly-make-molecule", 3, 0, 0, (Scheme_function_unknown) make_molecule); - scm_c_define_gsubr ("ly-combine-molecule-at-edge", 5 , 0, 0, (Scheme_function_unknown) Molecule::ly_molecule_combined_at_edge); - scm_c_define_gsubr ("ly-set-molecule-extent!", 3 , 0, 0, (Scheme_function_unknown) Molecule::ly_set_molecule_extent_x); - scm_c_define_gsubr ("ly-get-molecule-extent", 2 , 0, 0, (Scheme_function_unknown) Molecule::ly_get_molecule_extent); + SCM_ASSERT_TYPE(unsmob_molecule (mol), mol, SCM_ARG1, __FUNCTION__, "molecule"); + SCM_ASSERT_TYPE(ly_axis_p (axis), axis, SCM_ARG2, __FUNCTION__, "axis"); + SCM_ASSERT_TYPE(ly_dir_p (dir), dir, SCM_ARG3, __FUNCTION__, "dir"); + + unsmob_molecule (mol)->align_to ((Axis)gh_scm2int (axis), Direction (gh_scm2int (dir))); + + return SCM_UNDEFINED; } -ADD_SCM_INIT_FUNC (molecule,molecule_init); + +/* + Hmm... maybe this is not such a good idea ; stuff can be empty, + while expr_ == '() + */ bool Molecule::empty_b () const { return expr_ == SCM_EOL; } -SCM -fontify_atom (Font_metric * met, SCM f) -{ - if (f == SCM_EOL) - return f; - else - return scm_list_n (ly_symbol2scm ("fontify"), - ly_quote_scm (met->description_), f, SCM_UNDEFINED); -} - SCM Molecule::get_expr () const { @@ -243,13 +320,14 @@ IMPLEMENT_SIMPLE_SMOBS (Molecule); int -Molecule::print_smob (SCM s, SCM port, scm_print_state *) +Molecule::print_smob (SCM , SCM port, scm_print_state *) { - Molecule *r = (Molecule *) ly_cdr (s); - scm_puts ("#str ()); - scm_puts ((char *)str.ch_C (), port);*/ +#if 0 + Molecule *r = (Molecule *) ly_cdr (s); + String string (r->string ()); + scm_puts ((char *)str.to_str0 (), port); +#endif scm_puts (" >", port); return 1; @@ -264,6 +342,6 @@ Molecule::mark_smob (SCM s) return r->expr_; } -IMPLEMENT_TYPE_P (Molecule, "molecule?"); +IMPLEMENT_TYPE_P (Molecule, "ly:molecule?"); IMPLEMENT_DEFAULT_EQUAL_P (Molecule); -IMPLEMENT_UNSMOB (Molecule, molecule); +