]> git.donarmstrong.com Git - lilypond.git/blob - lily/line-interface.cc
use classnames for interface naming; remove inclusion of
[lilypond.git] / lily / line-interface.cc
1 /*
2   line-interface.cc -- implement Line_interface
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "line-interface.hh"
10
11 #include "staff-symbol-referencer.hh"
12 #include "lookup.hh"
13 #include "output-def.hh"
14 #include "grob.hh"
15
16 Stencil
17 Line_interface::make_arrow (Offset begin, Offset end,
18                             Real thick,
19                             Real length, Real width)
20 {
21   Real angle = (end - begin).arg ();
22   vector<Offset> points;
23
24   points.push_back (Offset (0, 0));
25   points.push_back (Offset (-length, width));
26   points.push_back (Offset (-length, -width));
27
28   for (vsize i = 0; i < points.size (); i++)
29     points[i] = points[i] * complex_exp (Offset (0, angle)) + end;
30
31   return Lookup::round_filled_polygon (points, thick);
32 }
33
34 Stencil
35 Line_interface::make_dashed_line (Real thick, Offset from, Offset to,
36                                   Real dash_period, Real dash_fraction)
37 {
38   dash_fraction = min (max (dash_fraction, 0.0), 1.0);
39   Real on = dash_fraction * dash_period + thick;
40   Real off = dash_period - on;
41
42   SCM at = scm_list_n (ly_symbol2scm ("dashed-line"),
43                        scm_from_double (thick),
44                        scm_from_double (on),
45                        scm_from_double (off),
46                        scm_from_double (to[X_AXIS] - from[X_AXIS]),
47                        scm_from_double (to[Y_AXIS] - from[Y_AXIS]),
48                        scm_from_double (0.0),
49                        SCM_UNDEFINED);
50
51   Box box;
52   box.add_point (Offset (0, 0));
53   box.add_point (to - from);
54
55   box[X_AXIS].widen (thick / 2);
56   box[Y_AXIS].widen (thick / 2);
57
58   Stencil m = Stencil (box, at);
59   m.translate (from);
60   return m;
61 }
62
63 Stencil
64 Line_interface::make_line (Real th, Offset from, Offset to)
65 {
66   SCM at = scm_list_n (ly_symbol2scm ("draw-line"),
67                        scm_from_double (th),
68                        scm_from_double (from[X_AXIS]),
69                        scm_from_double (from[Y_AXIS]),
70                        scm_from_double (to[X_AXIS]),
71                        scm_from_double (to[Y_AXIS]),
72                        SCM_UNDEFINED);
73
74   Box box;
75   box.add_point (from);
76   box.add_point (to);
77
78   box[X_AXIS].widen (th / 2);
79   box[Y_AXIS].widen (th / 2);
80
81   return Stencil (box, at);
82 }
83
84 Stencil
85 Line_interface::arrows (Grob *me, Offset from, Offset to,
86                         bool from_arrow,
87                         bool to_arrow)
88 {
89   Stencil a;
90   if (from_arrow || to_arrow)
91     {
92       Real thick = Staff_symbol_referencer::line_thickness (me)
93         * robust_scm2double (me->get_property ("thickness"), 1);
94       Real ss = Staff_symbol_referencer::staff_space (me);
95
96       Real len = robust_scm2double (me->get_property ("arrow-length"), 1.3 * ss);
97       Real wid = robust_scm2double (me->get_property ("arrow-width"), 0.5 * ss);
98
99       if (to_arrow)
100         a.add_stencil (make_arrow (from, to, thick, len, wid));
101
102       if (from_arrow)
103         a.add_stencil (make_arrow (to, from, thick, len, wid));
104     }
105
106   return a;
107 }
108
109 Stencil
110 Line_interface::line (Grob *me, Offset from, Offset to)
111 {
112   Real thick = Staff_symbol_referencer::line_thickness (me)
113     * robust_scm2double (me->get_property ("thickness"), 1);
114
115   SCM type = me->get_property ("style");
116
117   Stencil stil;
118
119   SCM dash_fraction = me->get_property ("dash-fraction");
120   if (scm_is_number (dash_fraction) || type == ly_symbol2scm ("dotted-line"))
121     {
122
123       Real fraction
124         = type == ly_symbol2scm ("dotted-line")
125         ? 0.0
126         : robust_scm2double (dash_fraction, 0.4);
127
128       fraction = min (max (fraction, 0.0), 1.0);
129       Real period = Staff_symbol_referencer::staff_space (me)
130         * robust_scm2double (me->get_property ("dash-period"), 1.0);
131
132       if (period < 0)
133         return Stencil ();
134
135       stil = make_dashed_line (thick, from, to, period, fraction);
136     }
137   else
138     stil = make_line (thick, from, to);
139
140   return stil;
141 }
142
143 ADD_INTERFACE (Line_interface,
144                "Generic line objects. Any object using lines supports this.  Normally, "
145                "you get a straight line. If @code{dash-period} is defined, a dashed line is "
146                "produced; the length of the dashes is tuned with "
147                "@code{dash-fraction}. If the latter is set to 0, a dotted line is "
148                "produced. If @code{dash-fraction} is negative, the line is made "
149                "transparent.",
150
151                /* properties */
152                "dash-period "
153                "dash-fraction "
154                "thickness "
155                "style "
156                "arrow-length "
157                "arrow-width")