2 custos.cc -- implement Custos
4 source file of the GNU LilyPond music typesetter
6 (C) 2000 Juergen Reuter <reuterj@ira.uka.de>
11 - merge create_ledger_line () and Note_head::create_ledger_line ()
14 - rewrite create_ledger_line () to support short and thin ledger lines
16 - do not show if a clef change immediately follows in the next line
18 - make custos direction control configurable
20 - decide: do or do not print custos if the next line starts with a rest
26 #include "staff-symbol-referencer.hh"
28 #include "molecule.hh"
30 #include "note-head.hh"
32 #include "font-interface.hh"
35 This function is a patched and hopefully much more understandable
36 rewrite of Note_head::ledger_line (). It still has some
39 (1) The term thick/2 probably should be thick*2 (probably a bug,
42 (2) The minimal width of the resulting ledger line equals the width
43 of the noteheads-ledgerending symbol (a limitation):
45 (---- left ledger ending
46 ----) right ledger ending
47 (---) resulting ledger line (just ok)
49 If x_extent ("xwid" in Note_head) is less than the width of the
50 ledger ending, the width of the total ledger line is even *greater*
51 than the width of a ledger ending (I would call this a bug). In
52 the below code, the condition "if (x_extent.length () >
53 slice_x_extent.length ())" avoids outputting the left ending in such
54 cases (rather a silly workaround, but better than nothing).
56 (---- left ledger ending
57 ----) right ledger ending
58 (-) desired ledger line
59 ------- resulting ledger line (too long)
60 ----) resulting ledger line with additional "if" (still too long)
62 The algorithm works properly only for a desired ledger line width
63 greater than the width of the ledger ending:
65 (---- left ledger ending
66 ----) right ledger ending
67 (------) desired ledger line
68 (------) resulting ledger line (ok)
70 * (3) The thickness of the ledger line is fixed (limitation).
73 Custos::create_ledger_line (Interval x_extent
, Grob
*me
)
76 Molecule slice
= Font_interface::get_default_font (me
)->find_by_name ("noteheads-ledgerending");
77 Interval slice_x_extent
= slice
.extent (X_AXIS
);
78 Interval slice_y_extent
= slice
.extent (Y_AXIS
);
80 // Create left ending of ledger line.
81 Molecule left_ending
= slice
;
82 left_ending
.translate_axis (x_extent
[LEFT
] - slice_x_extent
[LEFT
], X_AXIS
);
83 if (x_extent
.length () > slice_x_extent
.length ())
84 line
.add_molecule (left_ending
);
86 // Create right ending of ledger line.
87 Molecule right_ending
= slice
;
88 right_ending
.translate_axis (x_extent
[RIGHT
] - slice_x_extent
[RIGHT
],
90 line
.add_molecule (right_ending
);
92 // Fill out space between left and right ending of ledger line by
93 // lining up a series of slices in a row between them.
94 Molecule fill_out_slice
= left_ending
;
95 Real thick
= slice_y_extent
.length ();
96 Real delta_x
= slice_x_extent
.length () - thick
;
97 Real xpos
= x_extent
[LEFT
] + 2*delta_x
+ thick
/2; // TODO: check: thick*2?
98 while (xpos
<= x_extent
[RIGHT
])
100 fill_out_slice
.translate_axis (delta_x
, X_AXIS
);
101 line
.add_molecule (fill_out_slice
);
109 Custos::add_streepjes (Grob
* me
,
114 // TODO: This is (almost) duplicated code (see
115 // Note_head::brew_molecule). Junk me.
116 Real inter_f
= Staff_symbol_referencer::staff_space (me
)/2;
117 int streepjes_i
= abs (pos
) < interspaces
119 : (abs (pos
) - interspaces
) /2;
122 Direction dir
= (Direction
)sign (pos
);
123 Molecule
ledger_line (create_ledger_line (custos_p_
->extent (X_AXIS
),
125 ledger_line
.set_empty (true);
126 Real offs
= (Staff_symbol_referencer::on_staffline (me
))
129 for (int i
= 0; i
< streepjes_i
; i
++)
131 Molecule
streep (ledger_line
);
132 streep
.translate_axis (-dir
* inter_f
* i
* 2 + offs
,
134 custos_p_
->add_molecule (streep
);
139 MAKE_SCHEME_CALLBACK (Custos
,brew_molecule
,1);
141 Custos::brew_molecule (SCM smob
)
143 Item
*me
= (Item
*)unsmob_grob (smob
);
144 SCM scm_style
= me
->get_grob_property ("style");
146 if (gh_symbol_p (scm_style
))
148 String style
= ly_scm2string (scm_symbol_to_string (scm_style
));
150 String idx
= "custodes-";
151 int interspaces
= Staff_symbol_referencer::line_count (me
)-1;
153 Real pos
= Staff_symbol_referencer::position_f (me
);
155 if (pos
> (interspaces
/2 + 1)) // TODO: make this rule configurable
159 = Font_interface::get_default_font (me
)->find_by_name (idx
);
160 if (molecule
.empty_b ())
162 String message
= "unknown custos style: `" + style
+ "'";
163 warning (_ (message
.ch_C ()));
168 add_streepjes (me
, (int)pos
, interspaces
, &molecule
);
169 return molecule
.smobbed_copy ();
177 Custos::has_interface (Grob
*m
)
179 return m
&& m
->has_interface (ly_symbol2scm ("custos-interface"));