(readPostTable): ugh. Kludge: nglyphs in maxp
[lilypond.git] / lily / mensural-ligature.cc
bloba70eeaf113a3556d10e5cf241cdaaf34a7a76411
1 /*
2 mensural-ligature.cc -- implement Mensural_ligature
4 source file of the GNU LilyPond music typesetter
6 (c) 2002--2005 Juergen Reuter <reuter@ipd.uka.de>,
7 Pal Benko <benkop@freestart.hu>
8 */
10 #include <math.h>
12 #include "mensural-ligature.hh"
13 #include "item.hh"
14 #include "font-interface.hh"
15 #include "lookup.hh"
16 #include "staff-symbol-referencer.hh"
17 #include "note-head.hh"
18 #include "output-def.hh"
19 #include "warn.hh"
22 * TODO: divide this function into mensural and neo-mensural style.
24 * TODO: move this function to class Lookup?
26 Stencil
27 brew_flexa (Grob *me,
28 Real interval,
29 bool solid,
30 Real width,
31 Real vertical_line_thickness)
33 Real staff_space = Staff_symbol_referencer::staff_space (me);
34 Real slope = (interval / 2.0 * staff_space) / width;
36 // Compensate optical illusion regarding vertical position of left
37 // and right endings due to slope.
38 Real ypos_correction = -0.1 * staff_space * sign (slope);
39 Real slope_correction = 0.2 * staff_space * sign (slope);
40 Real corrected_slope = slope + slope_correction / width;
42 Stencil stencil;
43 if (solid) // colorated flexae
45 Stencil solid_head
46 = Lookup::beam (corrected_slope, width, staff_space, 0.0);
47 stencil.add_stencil (solid_head);
49 else // outline
52 The thickness of the horizontal lines of the flexa shape
53 should be equal to that of the horizontal lines of the
54 neomensural brevis note head (see mf/parmesan-heads.mf).
56 Real const horizontal_line_thickness = staff_space * 0.35;
58 // URGH! vertical_line_thickness is adjustable (via thickness
59 // property), while horizontal_line_thickness is constant.
60 // Maybe both should be adjustable independently?
62 Real height = staff_space - horizontal_line_thickness;
64 Stencil left_edge
65 = Lookup::beam (corrected_slope, vertical_line_thickness, height, 0.0);
66 stencil.add_stencil (left_edge);
68 Stencil right_edge
69 = Lookup::beam (corrected_slope, vertical_line_thickness, height, 0.0);
70 right_edge.translate_axis (width - vertical_line_thickness, X_AXIS);
71 right_edge.translate_axis ((width - vertical_line_thickness) *
72 corrected_slope, Y_AXIS);
73 stencil.add_stencil (right_edge);
75 Stencil bottom_edge
76 = Lookup::beam (corrected_slope, width,
77 horizontal_line_thickness, 0.0);
78 bottom_edge.translate_axis (-0.5 * height, Y_AXIS);
79 stencil.add_stencil (bottom_edge);
81 Stencil top_edge
82 = Lookup::beam (corrected_slope, width,
83 horizontal_line_thickness, 0.0);
84 top_edge.translate_axis (+0.5 * height, Y_AXIS);
85 stencil.add_stencil (top_edge);
87 stencil.translate_axis (ypos_correction, Y_AXIS);
88 return stencil;
91 Stencil
92 internal_brew_primitive (Grob *me)
94 SCM primitive_scm = me->get_property ("primitive");
95 if (primitive_scm == SCM_EOL)
97 programming_error ("Mensural_ligature: "
98 "undefined primitive -> ignoring grob");
99 return Stencil ();
101 int primitive = scm_to_int (primitive_scm);
103 Stencil out;
104 int delta_pitch = 0;
105 Real thickness = 0.0;
106 Real width = 0.0;
107 Real staff_space = Staff_symbol_referencer::staff_space (me);
108 if (primitive & MLP_ANY)
110 thickness = robust_scm2double (me->get_property ("thickness"), .14);
113 if (primitive & MLP_FLEXA)
115 delta_pitch = robust_scm2int (me->get_property ("delta-pitch"),
117 width
118 = robust_scm2double (me->get_property ("flexa-width"), 2.0 * staff_space);
120 if (primitive & MLP_SINGLE_HEAD)
122 width = robust_scm2double (me->get_property ("head-width"), staff_space);
125 switch (primitive & MLP_ANY)
127 case MLP_NONE:
128 return Stencil ();
129 case MLP_LONGA: // mensural brevis head with right cauda
130 out = Font_interface::get_default_font (me)->find_by_name
131 ("noteheads.s-2mensural");
132 break;
133 case MLP_BREVIS: // mensural brevis head
134 out = Font_interface::get_default_font (me)->find_by_name
135 ("noteheads.s-1mensural");
136 break;
137 case MLP_MAXIMA: // should be mensural maxima head without stem
138 out = Font_interface::get_default_font (me)->find_by_name
139 ("noteheads.s-1neomensural");
140 break;
141 case MLP_FLEXA:
142 out = brew_flexa (me, delta_pitch, false, width, thickness);
143 break;
144 default:
145 programming_error (_f ("Mensural_ligature: "
146 "unexpected case fall-through"));
147 return Stencil ();
150 Real blotdiameter
151 = (me->get_layout ()->get_dimension (ly_symbol2scm ("blotdiameter")));
153 if (primitive & MLP_STEM)
155 // assume MLP_UP
156 Real y_bottom = 0.0, y_top = 3.0 * staff_space;
158 if (primitive & MLP_DOWN)
160 y_bottom = -y_top;
161 y_top = 0.0;
164 Interval x_extent (0, thickness);
165 Interval y_extent (y_bottom, y_top);
166 Box join_box (x_extent, y_extent);
168 Stencil join = Lookup::round_filled_box (join_box, blotdiameter);
169 out.add_stencil (join);
172 SCM join_right_scm = me->get_property ("join-right-amount");
174 if (join_right_scm != SCM_EOL)
176 int join_right = scm_to_int (join_right_scm);
177 if (join_right)
179 Real y_top = join_right * 0.5 * staff_space;
180 Real y_bottom = 0.0;
182 if (y_top < 0.0)
184 y_bottom = y_top;
185 y_top = 0.0;
188 Interval x_extent (width - thickness, width);
189 Interval y_extent (y_bottom, y_top);
190 Box join_box (x_extent, y_extent);
191 Stencil join = Lookup::round_filled_box (join_box, blotdiameter);
193 out.add_stencil (join);
195 else
197 programming_error (_f ("Mensural_ligature: (join_right == 0)"));
201 #if 0 // what happend with the ledger lines?
202 int pos = Staff_symbol_referencer::get_rounded_position (me);
203 if (primitive & MLP_FLEXA)
205 pos += delta_pitch;
206 add_ledger_lines (me, &out, pos, 0.5 * delta_pitch, ledger_take_space);
208 #endif
210 return out;
213 MAKE_SCHEME_CALLBACK (Mensural_ligature, brew_ligature_primitive, 1);
215 Mensural_ligature::brew_ligature_primitive (SCM smob)
217 Grob *me = unsmob_grob (smob);
218 return internal_brew_primitive (me).smobbed_copy ();
221 MAKE_SCHEME_CALLBACK (Mensural_ligature, print, 1);
223 Mensural_ligature::print (SCM)
225 return SCM_EOL;
228 ADD_INTERFACE (Mensural_ligature, "mensural-ligature-interface",
229 "A mensural ligature",
230 "delta-pitch flexa-width head-width join-right-amount " // "add-join "
231 "ligature-primitive-callback primitive thickness");