* stepmake/stepmake/metafont-rules.make: backport 1.7 fixes.
[lilypond.git] / lily / hyphen-spanner.cc
blobee5c20bc204e50414fe0876e0a50215e3b700d32
1 /*
2 hyphen-spanner.cc -- implement Hyphen_spanner
4 source file of the GNU LilyPond music typesetter
6 (c) 1999 Glen Prideaux <glenprideaux@iname.com>
8 (adapted from lyric-extender)
9 */
11 #include <math.h>
13 #include "box.hh"
14 #include "lookup.hh"
15 #include "molecule.hh"
16 #include "paper-def.hh"
17 #include "hyphen-spanner.hh"
18 #include "paper-column.hh"
19 #include "spanner.hh"
20 #include "item.hh"
22 MAKE_SCHEME_CALLBACK (Hyphen_spanner,brew_molecule,1)
24 SCM
25 Hyphen_spanner::brew_molecule (SCM smob)
27 Spanner * sp = unsmob_spanner (smob);
29 Grob * common = sp;
30 Direction d = LEFT;
33 common = common->common_refpoint (sp->get_bound (d), X_AXIS);
35 while (flip (&d) != LEFT);
36 Interval bounds;
40 Interval iv = sp->get_bound (d)->extent (common, X_AXIS);
42 bounds[d] = iv.empty_b ()
43 ? sp->get_bound (d)->relative_coordinate (common, X_AXIS)
44 : iv[-d];
46 while (flip (&d) != LEFT);
48 Real lt = sp->get_paper ()->get_var ("linethickness");
49 Real th = gh_scm2double (sp->get_grob_property ("thickness")) * lt ;
50 Real h = gh_scm2double (sp->get_grob_property ("height"));
52 // interval?
53 Real l = gh_scm2double (sp->get_grob_property ("minimum-length"));
54 Real x = gh_scm2double (sp->get_grob_property ("maximum-length"));
55 // The hyphen can exist in the word space of the left lyric ...
56 SCM space = sp->get_bound (LEFT)->get_grob_property ("word-space");
57 if (gh_number_p (space))
59 bounds[LEFT] -= gh_scm2double (space);
63 we should probably do something more intelligent when bounds is
64 empty, but at least this doesn't crash.
65 */
66 Real w = bounds.empty_b () ? 0 : bounds.length ();
68 /* for length, use a geometric mean of the available space and some minimum
70 if (l < w)
72 l = sqrt (l*w);
73 if (l > x)
74 l = x;
76 else
78 /* OK, we have a problem. Usually this means that we're on the
79 first column, and we have a long lyric which extends to near
80 the offset for stuff */
81 /* This test for being on the first column has been shamelessly
82 ripped from spanner.cc */
83 Paper_column *sc = dynamic_cast<Paper_column*> (sp->get_bound (LEFT)->get_column ());
84 if (sc != NULL &&
85 sc->break_status_dir () == RIGHT)
87 /* We are on the first column, so it's probably harmless to
88 get the minimum length back by extending leftwards into
89 the space under the clef/key sig/time sig */
90 bounds[LEFT] = bounds[RIGHT] - l;
92 else
94 /* We can't get the length desired. Maybe we should warn. */
95 l = w;
98 Box b (Interval (-l/2,l/2), Interval (h,h+th));
99 Molecule mol (Lookup::filledbox (b));
100 Real ct = bounds.empty_b () ? 0 : bounds.center () ;
101 mol.translate_axis (ct -sp->relative_coordinate (common, X_AXIS), X_AXIS);
102 return mol.smobbed_copy ();
105 void
106 Hyphen_spanner::set_textitem (Direction d, Grob* b)
108 elt_->set_bound (d, b);
109 elt_->add_dependency (b);
112 Hyphen_spanner::Hyphen_spanner (Spanner*s)
114 elt_ = s;
119 ADD_INTERFACE (Hyphen_spanner, "lyric-hyphen-interface",
120 "A centred hyphen is a simple line between lyrics used to divide
121 syllables. The length of the hyphen line should stretch based on the
122 size of the gap between syllables.",
123 "thickness height minimum-length maximum-length word-space");