2 mensural-ligature.cc -- implement Mensural_ligature
4 source file of the GNU LilyPond music typesetter
6 (c) 2002--2004 Juergen Reuter <reuter@ipd.uka.de>
11 #include "mensural-ligature.hh"
12 #include "font-interface.hh"
15 #include "staff-symbol-referencer.hh"
16 #include "note-head.hh"
17 #include "output-def.hh"
21 * TODO: divide this function into mensural and neo-mensural style.
23 * TODO: move this function to class Lookup?
32 Direction cauda_direction)
34 Real staff_space = Staff_symbol_referencer::staff_space (me);
35 Real height = 0.6 * staff_space;
40 bool consider_interval =
41 cauda_direction * interval > 0.0;
43 Interval cauda_box_x (0, thickness);
46 if (consider_interval)
48 Real y_length = max (interval/2.0*staff_space, 1.2*staff_space);
49 cauda_box_y = Interval (0, y_length);
52 cauda_box_y = Interval (0, staff_space);
55 (cauda_direction == UP) ?
57 -0.5*height - cauda_box_y.length ();
59 Box cauda_box (cauda_box_x, cauda_box_y);
60 Stencil cauda = Lookup::filled_box (cauda_box);
61 cauda.translate_axis (y_correction, Y_AXIS);
62 stencil.add_stencil (cauda);
65 Real slope = (interval / 2.0 * staff_space) / width;
67 // Compensate optical illusion regarding vertical position of left
68 // and right endings due to slope.
69 Real ypos_correction = -0.1*staff_space * sign (slope);
70 Real slope_correction = 0.2*staff_space * sign (slope);
71 Real corrected_slope = slope + slope_correction/width;
76 Lookup::beam (corrected_slope, width, height, 0.0);
77 stencil.add_stencil (solid_head);
82 Lookup::beam (corrected_slope, thickness, height, 0.0);
83 stencil.add_stencil (left_edge);
86 Lookup::beam (corrected_slope, thickness, height, 0.0);
87 right_edge.translate_axis (width-thickness, X_AXIS);
88 right_edge.translate_axis (corrected_slope * (width-thickness), Y_AXIS);
89 stencil.add_stencil (right_edge);
92 Lookup::beam (corrected_slope, width, thickness, 0.0);
93 bottom_edge.translate_axis (-0.5*height, Y_AXIS);
94 stencil.add_stencil (bottom_edge);
97 Lookup::beam (corrected_slope, width, thickness, 0.0);
98 top_edge.translate_axis (+0.5*height, Y_AXIS);
99 stencil.add_stencil (top_edge);
101 stencil.translate_axis (ypos_correction, Y_AXIS);
106 internal_brew_primitive (Grob *me)
108 SCM primitive_scm = me->get_property ("primitive");
109 if (primitive_scm == SCM_EOL)
111 programming_error ("Mensural_ligature:"
112 "undefined primitive -> ignoring grob");
117 int primitive = ly_scm2int (primitive_scm);
119 Real thickness = 0.0;
120 Real flexa_width = 0.0;
121 Real staff_space = Staff_symbol_referencer::staff_space (me);
122 if (primitive & MLP_ANY)
124 thickness = robust_scm2double ( me->get_property ("thickness"), .14);
127 if (primitive & MLP_FLEXA)
129 delta_pitch = robust_scm2int (me->get_property ("delta-pitch"),
132 flexa_width = robust_scm2double (me->get_property ("flexa-width"), 2.0 * staff_space);
140 out = brew_flexa (me, delta_pitch, false,
141 flexa_width, thickness, true, DOWN);
144 out = Font_interface::get_default_font (me)->find_by_name ("noteheads--2mensural");
147 out = Font_interface::get_default_font (me)->find_by_name ("noteheads--1mensural");
150 out = Font_interface::get_default_font (me)->find_by_name ("noteheads-lmensural");
153 out = brew_flexa (me, delta_pitch, false,
154 flexa_width, thickness, true, UP);
157 out = brew_flexa (me, delta_pitch, false,
158 flexa_width, thickness, false, CENTER);
161 programming_error (_f ("Mensural_ligature:"
162 "unexpected case fall-through"));
166 SCM join_left_scm = me->get_property ("join-left-amount");
167 if (join_left_scm != SCM_EOL)
169 int join_left = ly_scm2int (join_left_scm);
171 programming_error (_f ("Mensural_ligature: (join_left == 0)"));
172 Real blotdiameter = (me->get_paper ()->get_dimension (ly_symbol2scm ("blotdiameter")));
173 Interval x_extent = Interval (0, thickness);
174 Interval y_extent = (join_left > 0) ?
175 Interval (-join_left * 0.5 * staff_space, 0) :
176 Interval (0, -join_left * 0.5 * staff_space);
177 Box join_box (x_extent, y_extent);
179 Stencil join = Lookup::round_filled_box (join_box, blotdiameter);
180 out.add_stencil (join);
183 int pos = Staff_symbol_referencer::get_rounded_position (me);
184 if (primitive & MLP_FLEXA)
192 MAKE_SCHEME_CALLBACK (Mensural_ligature, brew_ligature_primitive, 1);
194 Mensural_ligature::brew_ligature_primitive (SCM smob)
196 Grob *me = unsmob_grob (smob);
197 return internal_brew_primitive (me).smobbed_copy ();
200 MAKE_SCHEME_CALLBACK (Mensural_ligature, print, 1);
202 Mensural_ligature::print (SCM)
207 ADD_INTERFACE (Mensural_ligature, "mensural-ligature-interface",
208 "A mensural ligature",
209 "delta-pitch flexa-width head-width join-left join-left-amount "
210 "ligature-primitive-callback primitive thickness");