2 ottava-bracket.cc -- implement Ottava_bracket
4 source file of the GNU LilyPond music typesetter
6 (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
11 #include "text-item.hh"
12 #include "text-spanner.hh"
13 #include "line-spanner.hh"
15 #include "font-interface.hh"
16 #include "dimensions.hh"
17 #include "paper-def.hh"
19 #include "paper-column.hh"
20 #include "staff-symbol-referencer.hh"
21 #include "note-column.hh"
22 #include "directional-element-interface.hh"
23 #include "tuplet-bracket.hh"
27 DECLARE_SCHEME_CALLBACK (print
, (SCM
));
28 static bool has_interface (Grob
*);
33 TODO: the string for ottava shoudl depend on the available space, ie.
36 Long: 15ma Short: 15ma Empty: 15
42 MAKE_SCHEME_CALLBACK (Ottava_bracket
, print
, 1);
44 Ottava_bracket::print (SCM smob
)
46 Spanner
*me
= dynamic_cast<Spanner
*> (unsmob_grob (smob
));
51 Grob
*common
= me
->get_bound (LEFT
)->common_refpoint (me
->get_bound (RIGHT
), X_AXIS
);
52 Paper_def
* paper
= me
->get_paper ();
55 Drul_array
<bool> broken
;
59 Item
*b
= me
->get_bound (d
);
60 broken
[d
] = (b
->break_status_dir () != CENTER
);
62 if (Note_column::has_interface (b
))
64 common
= common_refpoint_of_list (b
->get_property ("heads"), common
, X_AXIS
);
67 while (flip (&d
) != LEFT
);
69 SCM properties
= Font_interface::text_font_alist_chain (me
);
70 SCM markup
= me
->get_property ("text");
72 if (Text_item::markup_p (markup
))
73 text
= *unsmob_stencil (Text_item::interpret_markup (paper
->self_scm (), properties
, markup
));
76 Drul_array
<Real
> shorten
= robust_scm2interval (me
->get_property ("shorten-pair"),
81 TODO: we should check if there are ledgers, and modify length of
86 Item
*b
= me
->get_bound (d
);
89 if (Note_column::has_interface (b
))
91 for (SCM s
= b
->get_property ("note-heads"); ly_pair_p (s
); s
=ly_cdr (s
))
92 ext
.unite (unsmob_grob (ly_car (s
))->extent (common
, X_AXIS
));
98 span_points
[d
] = (broken
[d
]) ? b
->extent (common
, X_AXIS
)[-d
] : ext
[d
];
103 while (flip (&d
) != LEFT
);
107 0.3 is ~ italic correction.
109 Real text_size
= text
.extent (X_AXIS
).is_empty ()
110 ? 0.0 : text
.extent (X_AXIS
)[RIGHT
] + 0.3;
112 span_points
[LEFT
] = span_points
[LEFT
]
113 <? (span_points
[RIGHT
] - text_size
114 - robust_scm2double (me
->get_property ("minimum-length"), -1.0));
116 Interval bracket_span_points
= span_points
;
117 bracket_span_points
[LEFT
] += text_size
;
119 Drul_array
<Real
> edge_height
= robust_scm2interval (me
->get_property ("edge-height"),
120 Interval (1.0, 1.0));
123 Drul_array
<Real
> flare
= robust_scm2interval (me
->get_property ("bracket-flare"),
128 edge_height
[LEFT
] = 0.0;
129 edge_height
[RIGHT
] *= - get_grob_direction (me
);
131 edge_height
[RIGHT
] = 0.0;
135 if (!bracket_span_points
.is_empty () && bracket_span_points
.length () > 0.001)
136 b
= Tuplet_bracket::make_bracket (me
,
137 Y_AXIS
, Offset (bracket_span_points
.length (), 0),
143 The vertical lines should not take space, for the following scenario:
151 Just a small amount, yes. In tight situations, it is even
152 possible to center the `8' directly below the note, dropping the
153 ottava line completely...
157 b
= Stencil (Box (b
.extent (X_AXIS
),
161 b
.translate_axis (bracket_span_points
[LEFT
], X_AXIS
);
162 text
.translate_axis (span_points
[LEFT
], X_AXIS
);
163 text
.align_to (Y_AXIS
, CENTER
);
164 b
.add_stencil (text
);
166 b
.translate_axis (- me
->relative_coordinate (common
, X_AXIS
), X_AXIS
);
168 return b
.smobbed_copy ();
172 ADD_INTERFACE (Ottava_bracket
, "ottava-bracket-interface",
174 "edge-height bracket-flare shorten-pair minimum-length");