2 line-interface.cc -- implement Line_interface
4 source file of the GNU LilyPond music typesetter
6 (c) 2004--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
9 #include "line-interface.hh"
11 #include "staff-symbol-referencer.hh"
13 #include "output-def.hh"
17 Line_interface::make_arrow (Offset begin, Offset end,
19 Real length, Real width)
21 Real angle = (end - begin).arg ();
22 vector<Offset> points;
24 points.push_back (Offset (0, 0));
25 points.push_back (Offset (-length, width));
26 points.push_back (Offset (-length, -width));
28 for (vsize i = 0; i < points.size (); i++)
29 points[i] = points[i] * complex_exp (Offset (0, angle)) + end;
31 return Lookup::round_filled_polygon (points, thick);
35 Line_interface::zigzag_stencil (Grob *me,
41 Real thick = Staff_symbol_referencer::line_thickness (me);
42 thick *= robust_scm2double (me->get_property ("thickness"), 1.0); // todo: staff sym referencer?
44 Real staff_space = Staff_symbol_referencer::staff_space (me);
46 Real w = robust_scm2double (me->get_property ("zigzag-width"), 1) * staff_space;
47 int count = (int) ceil (dz.length () / w);
48 w = dz.length () / count;
50 Real l = robust_scm2double (me->get_property ("zigzag-length"), 1) * w;
51 Real h = l > w / 2 ? sqrt (l * l - w * w / 4) : 0;
53 Offset rotation_factor = complex_exp (Offset (0, dz.arg ()));
56 points[0] = Offset (0, -h / 2);
57 points[1] = Offset (w / 2, h / 2);
58 points[2] = Offset (w, -h / 2);
59 for (int i = 0; i < 3; i++)
60 points[i] = complex_multiply (points[i], rotation_factor);
62 Stencil squiggle (Line_interface::make_line (thick, points[0], points[1]));
63 squiggle.add_stencil (Line_interface::make_line (thick, points[1], points[2]));
66 for (int i = 0; i < count; i++)
68 Stencil moved_squiggle (squiggle);
69 moved_squiggle.translate (from + Offset (i * w, 0) * rotation_factor);
70 total.add_stencil (moved_squiggle);
74 b.add_point (Offset (0, 0));
76 b[X_AXIS].widen (thick / 2);
77 b[Y_AXIS].widen (thick / 2);
79 return Stencil (b, total.expr ());
84 Line_interface::make_dashed_line (Real thick, Offset from, Offset to,
85 Real dash_period, Real dash_fraction)
87 dash_fraction = min (max (dash_fraction, 0.0), 1.0);
88 Real on = dash_fraction * dash_period + thick;
89 Real off = dash_period - on;
91 SCM at = scm_list_n (ly_symbol2scm ("dashed-line"),
92 scm_from_double (thick),
94 scm_from_double (off),
95 scm_from_double (to[X_AXIS] - from[X_AXIS]),
96 scm_from_double (to[Y_AXIS] - from[Y_AXIS]),
97 scm_from_double (0.0),
101 box.add_point (Offset (0, 0));
102 box.add_point (to - from);
104 box[X_AXIS].widen (thick / 2);
105 box[Y_AXIS].widen (thick / 2);
107 Stencil m = Stencil (box, at);
113 Line_interface::make_line (Real th, Offset from, Offset to)
115 SCM at = scm_list_n (ly_symbol2scm ("draw-line"),
116 scm_from_double (th),
117 scm_from_double (from[X_AXIS]),
118 scm_from_double (from[Y_AXIS]),
119 scm_from_double (to[X_AXIS]),
120 scm_from_double (to[Y_AXIS]),
124 box.add_point (from);
127 box[X_AXIS].widen (th / 2);
128 box[Y_AXIS].widen (th / 2);
130 return Stencil (box, at);
134 Line_interface::arrows (Grob *me, Offset from, Offset to,
139 if (from_arrow || to_arrow)
141 Real thick = Staff_symbol_referencer::line_thickness (me)
142 * robust_scm2double (me->get_property ("thickness"), 1);
143 Real ss = Staff_symbol_referencer::staff_space (me);
145 Real len = robust_scm2double (me->get_property ("arrow-length"), 1.3 * ss);
146 Real wid = robust_scm2double (me->get_property ("arrow-width"), 0.5 * ss);
149 a.add_stencil (make_arrow (from, to, thick, len, wid));
152 a.add_stencil (make_arrow (to, from, thick, len, wid));
159 Line_interface::line (Grob *me, Offset from, Offset to)
161 Real thick = Staff_symbol_referencer::line_thickness (me)
162 * robust_scm2double (me->get_property ("thickness"), 1);
164 SCM type = me->get_property ("style");
165 if (type == ly_symbol2scm ("zigzag"))
167 return zigzag_stencil (me, from, to);
171 SCM dash_fraction = me->get_property ("dash-fraction");
172 if (scm_is_number (dash_fraction) || type == ly_symbol2scm ("dotted-line"))
176 = type == ly_symbol2scm ("dotted-line")
178 : robust_scm2double (dash_fraction, 0.4);
180 fraction = min (max (fraction, 0.0), 1.0);
181 Real period = Staff_symbol_referencer::staff_space (me)
182 * robust_scm2double (me->get_property ("dash-period"), 1.0);
187 stil = make_dashed_line (thick, from, to, period, fraction);
190 stil = make_line (thick, from, to);
195 ADD_INTERFACE (Line_interface,
196 "Generic line objects. Any object using lines supports this. Normally, "
197 "you get a straight line. If @code{dash-period} is defined, a dashed line is "
198 "produced; the length of the dashes is tuned with "
199 "@code{dash-fraction}. If the latter is set to 0, a dotted line is "
200 "produced. If @code{dash-fraction} is negative, the line is made "