~ubuntu-branches/ubuntu/precise/lilypond/precise

« back to all changes in this revision

Viewing changes to lily/ottava-bracket.cc

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Bushnell, BSG
  • Date: 2006-12-19 10:18:12 UTC
  • mfrom: (3.1.4 feisty)
  • Revision ID: james.westby@ubuntu.com-20061219101812-7awtjkp0i393wxty
Tags: 2.8.7-3
scripts/midi2ly.py: When setting DATADIR, find Lilypond python files
in the @TOPLEVEL_VERSION@ directory, not 'current'.  Patch thanks to
Chris Lamb (chris@chris-lamb.co.uk).  (Closes: #400550)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*   
2
 
  ottava-bracket.cc --  implement Ottava_bracket
 
1
/*
 
2
  ottava-bracket.cc -- implement Ottava_bracket
3
3
 
4
4
  source file of the GNU LilyPond music typesetter
5
5
 
6
 
  (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
7
 
 
8
 
 */
9
 
 
10
 
#include "stencil.hh"
11
 
#include "text-item.hh"
12
 
#include "text-spanner.hh"
 
6
  (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
7
*/
 
8
 
 
9
#include "text-interface.hh"
13
10
#include "line-spanner.hh"
14
11
#include "spanner.hh"
15
12
#include "font-interface.hh"
16
13
#include "dimensions.hh"
17
 
#include "paper-def.hh"
 
14
#include "output-def.hh"
18
15
#include "warn.hh"
19
16
#include "paper-column.hh"
20
17
#include "staff-symbol-referencer.hh"
21
18
#include "note-column.hh"
22
19
#include "directional-element-interface.hh"
23
20
#include "tuplet-bracket.hh"
 
21
#include "rhythmic-head.hh"
 
22
#include "pointer-group-interface.hh"
24
23
 
25
24
struct Ottava_bracket
26
25
{
27
26
  DECLARE_SCHEME_CALLBACK (print, (SCM));
28
 
  static bool has_interface (Grob*);
 
27
  static bool has_interface (Grob *);
29
28
};
30
29
 
31
 
 
32
30
/*
33
31
  TODO: the string for ottava shoudl depend on the available space, ie.
34
32
 
35
 
  
36
33
  Long: 15ma        Short: 15ma    Empty: 15
37
 
         8va                8va            8
38
 
         8va bassa          8ba            8
39
 
 
 
34
  8va                8va            8
 
35
  8va bassa          8ba            8
40
36
*/
41
 
 
42
37
MAKE_SCHEME_CALLBACK (Ottava_bracket, print, 1);
43
38
SCM
44
39
Ottava_bracket::print (SCM smob)
45
40
{
46
 
  Spanner*me  = dynamic_cast<Spanner*> (unsmob_grob (smob));
47
 
  
48
 
  
 
41
  Spanner *me = dynamic_cast<Spanner *> (unsmob_grob (smob));
49
42
  Interval span_points;
50
 
  
 
43
 
51
44
  Grob *common = me->get_bound (LEFT)->common_refpoint (me->get_bound (RIGHT), X_AXIS);
52
 
  Paper_def * paper = me->get_paper ();
 
45
  Output_def *layout = me->layout ();
53
46
 
54
 
  
55
47
  Drul_array<bool> broken;
56
48
  Direction d = LEFT;
57
49
  do
61
53
 
62
54
      if (Note_column::has_interface (b))
63
55
        {
64
 
          common = common_refpoint_of_list (b->get_property ("heads"), common, X_AXIS);
 
56
          extract_grob_set (b, "note-heads", heads);
 
57
          common = common_refpoint_of_array (heads, common, X_AXIS);
 
58
          for (vsize i = 0; i < heads.size (); i++)
 
59
            {
 
60
              Grob *h = heads[i];
 
61
              Grob *dots = Rhythmic_head::get_dots (h);
 
62
              if (dots)
 
63
                common = dots->common_refpoint (common, X_AXIS);
 
64
            }
65
65
        }
66
66
    }
67
67
  while (flip (&d) != LEFT);
69
69
  SCM properties = Font_interface::text_font_alist_chain (me);
70
70
  SCM markup = me->get_property ("text");
71
71
  Stencil text;
72
 
  if (Text_item::markup_p (markup)) 
73
 
    text = *unsmob_stencil (Text_item::interpret_markup (paper->self_scm (), properties, markup));
74
 
 
 
72
  if (Text_interface::is_markup (markup))
 
73
    text = *unsmob_stencil (Text_interface::interpret_markup (layout->self_scm (), properties, markup));
75
74
 
76
75
  Drul_array<Real> shorten = robust_scm2interval (me->get_property ("shorten-pair"),
77
 
                                                  Interval (0,0));
78
 
 
 
76
                                                  Interval (0, 0));
79
77
 
80
78
  /*
81
79
    TODO: we should check if there are ledgers, and modify length of
82
80
    the spanner to that.
83
 
   */
 
81
  */
84
82
  do
85
83
    {
86
84
      Item *b = me->get_bound (d);
88
86
      Interval ext;
89
87
      if (Note_column::has_interface (b))
90
88
        {
91
 
          for (SCM s = b->get_property ("note-heads"); gh_pair_p (s); s =gh_cdr (s))
92
 
            ext.unite (unsmob_grob (gh_car (s))->extent (common, X_AXIS));
 
89
          extract_grob_set (b, "note-heads", heads);
 
90
          for (vsize i = 0; i < heads.size (); i++)
 
91
            {
 
92
              Grob *h = heads[i];
 
93
              ext.unite (h->extent (common, X_AXIS));
 
94
              Grob *dots = Rhythmic_head::get_dots (h);
 
95
 
 
96
              if (dots && d == RIGHT)
 
97
                ext.unite (dots->extent (common, X_AXIS));
 
98
            }
93
99
        }
94
100
 
95
101
      if (ext.is_empty ())
96
 
        {
97
 
          Real x = b->relative_coordinate (common, X_AXIS);
98
 
          ext = Interval (x,x);
99
 
        }
100
 
      
101
 
      span_points[d] =  (broken [d]) ? b->extent (common, X_AXIS)[-d] : ext[d];
 
102
        ext = robust_relative_extent (b, common, X_AXIS);
102
103
 
103
104
      if (broken[d])
104
 
        shorten [d] = 0.0; 
 
105
        {
 
106
          span_points[d] = b->extent (common, X_AXIS)[RIGHT];
 
107
          shorten[d] = 0.;
 
108
        }
 
109
 
 
110
      else
 
111
        span_points[d] = ext[d];
105
112
    }
106
113
  while (flip (&d) != LEFT);
107
114
 
108
 
 
109
115
  /*
110
 
    0.3 is ~ italic correction. 
111
 
   */
112
 
  Real text_size =  text.extent (X_AXIS).is_empty ()
113
 
    ? 0.0 : text.extent (X_AXIS)[RIGHT] +  0.3;
114
 
  
115
 
  span_points[LEFT] = span_points[LEFT]
116
 
    <? (span_points[RIGHT] - text_size
117
 
        - robust_scm2double (me->get_property ("minimum-length"), -1.0)); 
118
 
  
 
116
    0.3 is ~ italic correction.
 
117
  */
 
118
  Real text_size = text.extent (X_AXIS).is_empty ()
 
119
    ? 0.0 : text.extent (X_AXIS)[RIGHT] + 0.3;
 
120
 
 
121
  span_points[LEFT]
 
122
    = min (span_points[LEFT],
 
123
           (span_points[RIGHT] - text_size
 
124
            - robust_scm2double (me->get_property ("minimum-length"), -1.0)));
 
125
 
119
126
  Interval bracket_span_points = span_points;
120
127
  bracket_span_points[LEFT] += text_size;
121
 
  
 
128
 
122
129
  Drul_array<Real> edge_height = robust_scm2interval (me->get_property ("edge-height"),
123
130
                                                      Interval (1.0, 1.0));
124
131
 
125
 
  
126
132
  Drul_array<Real> flare = robust_scm2interval (me->get_property ("bracket-flare"),
127
 
                                                Interval (0,0));
128
 
 
129
 
 
 
133
                                                Interval (0, 0));
130
134
 
131
135
  edge_height[LEFT] = 0.0;
132
 
  edge_height[RIGHT] *=  - get_grob_direction (me);
 
136
  edge_height[RIGHT] *= -get_grob_direction (me);
133
137
  if (broken[RIGHT])
134
138
    edge_height[RIGHT] = 0.0;
135
 
  
 
139
 
136
140
  Stencil b;
137
141
  Interval empty;
138
142
  if (!bracket_span_points.is_empty () && bracket_span_points.length () > 0.001)
139
143
    b = Tuplet_bracket::make_bracket (me,
140
144
                                      Y_AXIS, Offset (bracket_span_points.length (), 0),
141
 
                                       edge_height,
 
145
                                      edge_height,
142
146
                                      empty,
143
147
                                      flare, shorten);
144
148
 
146
150
    The vertical lines should not take space, for the following scenario:
147
151
 
148
152
    8 -----+
149
 
        o  |
150
 
       |
151
 
       |
152
 
       
 
153
    o  |
 
154
    |
 
155
    |
 
156
 
153
157
 
154
158
    Just a small amount, yes.  In tight situations, it is even
155
159
    possible to center the `8' directly below the note, dropping the
156
160
    ottava line completely...
157
161
 
158
162
  */
159
 
  
 
163
 
160
164
  b = Stencil (Box (b.extent (X_AXIS),
161
 
                     Interval (0.1,0.1)),
162
 
                b.get_expr ());
163
 
  
 
165
                    Interval (0.1, 0.1)),
 
166
               b.expr ());
 
167
 
164
168
  b.translate_axis (bracket_span_points[LEFT], X_AXIS);
165
169
  text.translate_axis (span_points[LEFT], X_AXIS);
166
170
  text.align_to (Y_AXIS, CENTER);
167
171
  b.add_stencil (text);
168
 
  
 
172
 
169
173
  b.translate_axis (- me->relative_coordinate (common, X_AXIS), X_AXIS);
170
 
  
171
 
  return b.smobbed_copy ();  
 
174
 
 
175
  return b.smobbed_copy ();
172
176
}
173
177
 
174
 
 
175
 
ADD_INTERFACE (Ottava_bracket, "ottava-bracket-interface",
 
178
ADD_INTERFACE (Ottava_bracket,
 
179
               "ottava-bracket-interface",
 
180
               
176
181
               "An ottava bracket",
177
 
               "edge-height bracket-flare shorten-pair minimum-length");
 
182
 
 
183
               /*
 
184
                 properties
 
185
                */
 
186
               "edge-height "
 
187
               "bracket-flare "
 
188
               "shorten-pair "
 
189
               "minimum-length");
178
190