Start pictograms branch.
[lilypond/mpolesky.git] / lily / mensural-ligature.cc
blobca0fe9b039174c2131c2b9f244e22ad6576cfa6b
1 /*
2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2002--2010 Juergen Reuter <reuter@ipd.uka.de>,
5 Pal Benko <benkop@freestart.hu>
7 LilyPond is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 LilyPond is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21 #include "mensural-ligature.hh"
23 #include "font-interface.hh"
24 #include "international.hh"
25 #include "item.hh"
26 #include "lookup.hh"
27 #include "note-head.hh"
28 #include "output-def.hh"
29 #include "staff-symbol-referencer.hh"
30 #include "warn.hh"
33 * TODO: divide this function into mensural and neo-mensural style.
35 * TODO: move this function to class Lookup?
37 Stencil
38 brew_flexa (Grob *me,
39 Real interval,
40 bool solid,
41 Real width,
42 Real vertical_line_thickness)
44 Real staff_space = Staff_symbol_referencer::staff_space (me);
45 Real slope = (interval / 2.0 * staff_space) / width;
47 // Compensate optical illusion regarding vertical position of left
48 // and right endings due to slope.
49 Real ypos_correction = -0.1 * staff_space * sign (slope);
50 Real slope_correction = 0.2 * staff_space * sign (slope);
51 Real corrected_slope = slope + slope_correction / width;
53 Stencil stencil;
54 if (solid) // colorated flexae
56 Stencil solid_head
57 = Lookup::beam (corrected_slope, width, staff_space, 0.0);
58 stencil.add_stencil (solid_head);
60 else // outline
63 The thickness of the horizontal lines of the flexa shape
64 should be equal to that of the horizontal lines of the
65 neomensural brevis note head (see mf/parmesan-heads.mf).
67 Real const horizontal_line_thickness = staff_space * 0.35;
69 // URGH! vertical_line_thickness is adjustable (via thickness
70 // property), while horizontal_line_thickness is constant.
71 // Maybe both should be adjustable independently?
73 Real height = staff_space - horizontal_line_thickness;
75 Stencil left_edge
76 = Lookup::beam (corrected_slope, vertical_line_thickness, height, 0.0);
77 stencil.add_stencil (left_edge);
79 Stencil right_edge
80 = Lookup::beam (corrected_slope, vertical_line_thickness, height, 0.0);
81 right_edge.translate_axis (width - vertical_line_thickness, X_AXIS);
82 right_edge.translate_axis ((width - vertical_line_thickness) *
83 corrected_slope, Y_AXIS);
84 stencil.add_stencil (right_edge);
86 Stencil bottom_edge
87 = Lookup::beam (corrected_slope, width,
88 horizontal_line_thickness, 0.0);
89 bottom_edge.translate_axis (-0.5 * height, Y_AXIS);
90 stencil.add_stencil (bottom_edge);
92 Stencil top_edge
93 = Lookup::beam (corrected_slope, width,
94 horizontal_line_thickness, 0.0);
95 top_edge.translate_axis (+0.5 * height, Y_AXIS);
96 stencil.add_stencil (top_edge);
98 stencil.translate_axis (ypos_correction, Y_AXIS);
99 return stencil;
102 Stencil
103 internal_brew_primitive (Grob *me)
105 SCM primitive_scm = me->get_property ("primitive");
106 if (primitive_scm == SCM_EOL)
108 programming_error ("Mensural_ligature:"
109 " undefined primitive -> ignoring grob");
110 return Lookup::blank (Box (Interval (0, 0), Interval (0, 0)));
112 int primitive = scm_to_int (primitive_scm);
114 Stencil out;
115 int delta_pitch = 0;
116 Real thickness = 0.0;
117 Real width = 0.0;
118 Real staff_space = Staff_symbol_referencer::staff_space (me);
119 if (primitive & MLP_ANY)
120 thickness = robust_scm2double (me->get_property ("thickness"), .14);
122 if (primitive & MLP_FLEXA)
124 delta_pitch = robust_scm2int (me->get_property ("delta-position"),
126 width
127 = robust_scm2double (me->get_property ("flexa-width"), 2.0 * staff_space);
129 if (primitive & MLP_SINGLE_HEAD)
130 width = robust_scm2double (me->get_property ("head-width"), staff_space);
132 switch (primitive & MLP_ANY)
134 case MLP_NONE:
135 return Lookup::blank (Box (Interval (0, 0), Interval (0, 0)));
136 case MLP_LONGA: // mensural brevis head with right cauda
137 out = Font_interface::get_default_font (me)->find_by_name
138 ("noteheads.sM2mensural");
139 break;
140 case MLP_BREVIS: // mensural brevis head
141 out = Font_interface::get_default_font (me)->find_by_name
142 ("noteheads.sM1mensural");
143 break;
144 case MLP_MAXIMA: // should be mensural maxima head without stem
145 out = Font_interface::get_default_font (me)->find_by_name
146 ("noteheads.sM1neomensural");
147 break;
148 case MLP_FLEXA:
149 out = brew_flexa (me, delta_pitch, false, width, thickness);
150 break;
151 default:
152 programming_error (_ ("Mensural_ligature:"
153 " unexpected case fall-through"));
154 return Lookup::blank (Box (Interval (0, 0), Interval (0, 0)));
157 Real blotdiameter
158 = (me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")));
160 if (primitive & MLP_STEM)
162 // assume MLP_UP
163 Real y_bottom = 0.0, y_top = 3.0 * staff_space;
165 if (primitive & MLP_DOWN)
167 y_bottom = -y_top;
168 y_top = 0.0;
171 Interval x_extent (0, thickness);
172 Interval y_extent (y_bottom, y_top);
173 Box join_box (x_extent, y_extent);
175 Stencil join = Lookup::round_filled_box (join_box, blotdiameter);
176 out.add_stencil (join);
179 SCM join_right_scm = me->get_property ("join-right-amount");
181 if (scm_is_number (join_right_scm))
183 int join_right = scm_to_int (join_right_scm);
184 if (join_right)
186 Real y_top = join_right * 0.5 * staff_space;
187 Real y_bottom = 0.0;
189 if (y_top < 0.0)
191 y_bottom = y_top;
192 y_top = 0.0;
195 Interval x_extent (width - thickness, width);
196 Interval y_extent (y_bottom, y_top);
197 Box join_box (x_extent, y_extent);
198 Stencil join = Lookup::round_filled_box (join_box, blotdiameter);
200 out.add_stencil (join);
202 else
203 programming_error (_ ("Mensural_ligature: (join_right == 0)"));
206 #if 0 /* what happend with the ledger lines? */
207 int pos = Staff_symbol_referencer::get_rounded_position (me);
208 if (primitive & MLP_FLEXA)
210 pos += delta_pitch;
211 add_ledger_lines (me, &out, pos, 0.5 * delta_pitch, ledger_take_space);
213 #endif
215 return out;
218 MAKE_SCHEME_CALLBACK (Mensural_ligature, brew_ligature_primitive, 1);
220 Mensural_ligature::brew_ligature_primitive (SCM smob)
222 Grob *me = unsmob_grob (smob);
223 return internal_brew_primitive (me).smobbed_copy ();
226 MAKE_SCHEME_CALLBACK (Mensural_ligature, print, 1);
228 Mensural_ligature::print (SCM)
230 return SCM_EOL;
233 ADD_INTERFACE (Mensural_ligature,
234 "A mensural ligature.",
236 /* properties */
237 "delta-position "
238 "flexa-width "
239 "head-width "
240 "join-right-amount "
241 "primitive "
242 "thickness "