]> git.donarmstrong.com Git - lilypond.git/blob - lily/hyphen-spanner.cc
release: 1.5.47
[lilypond.git] / lily / hyphen-spanner.cc
1 /*
2   hyphen-spanner.cc -- implement Hyphen_spanner
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1999 Glen Prideaux <glenprideaux@iname.com>
7
8  (adapted from lyric-extender)
9 */
10
11 #include <math.h>
12
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"
21
22 MAKE_SCHEME_CALLBACK (Hyphen_spanner,brew_molecule,1)
23
24 SCM 
25 Hyphen_spanner::brew_molecule (SCM smob)
26 {
27   Spanner * sp = unsmob_spanner (smob);
28
29   Grob * common = sp;
30   Direction d = LEFT;
31   do
32     {
33       common = common->common_refpoint (sp->get_bound (d), X_AXIS);
34     }
35   while (flip (&d) != LEFT);
36   Interval bounds;
37   
38   do
39     {
40       Interval iv = sp->get_bound (d)->extent (common, X_AXIS);
41
42       bounds[d] = iv.empty_b ()
43         ? sp->get_bound (d)->relative_coordinate (common, X_AXIS)
44         : iv[-d];
45     }
46   while (flip (&d) != LEFT);
47   
48   Real lt = sp->paper_l ()->get_var ("stafflinethickness");
49   Real th = gh_scm2double (sp->get_grob_property ("thickness")) * lt ;
50   Real h = gh_scm2double (sp->get_grob_property ("height"));
51
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))
58     {
59       bounds[LEFT] -=  gh_scm2double (space);
60     }
61
62   /*
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 ();
67   
68   /* for length, use a geometric mean of the available space and some minimum
69    */
70   if (l < w)
71     {
72       l = sqrt (l*w);
73       if (l > x)
74         l = x;
75     }
76   else
77     {
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)->column_l ());
84       if (sc != NULL &&
85           sc->break_status_dir () == RIGHT)
86         {
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;
91         }
92       else 
93         {
94           /* We can't get the length desired. Maybe we should warn. */
95           l = w;
96         }
97     }
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 ();
103 }
104   
105 void
106 Hyphen_spanner::set_textitem (Direction d, Grob* b)
107 {
108   elt_l_->set_bound (d, b);
109   elt_l_->add_dependency (b);
110 }
111
112 Hyphen_spanner::Hyphen_spanner (Spanner*s)
113 {
114   elt_l_ = s;
115 }
116
117
118
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");
124