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