2 line-spanner.cc -- implement Line_spanner
4 source file of the GNU LilyPond music typesetter
6 (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
12 #include "line-spanner.hh"
13 #include "paper-def.hh"
14 #include "paper-column.hh"
15 #include "staff-symbol-referencer.hh"
18 Line_spanner::line_atom (Grob
* me
, Real dx
, Real dy
)
21 SCM type
= me
->get_grob_property ("type");
22 if (gh_symbol_p (type
)
23 && (type
== ly_symbol2scm ("line")
24 || type
== ly_symbol2scm ("dashed-line")
25 || type
== ly_symbol2scm ("dotted-line")))
27 Real staff_space
= Staff_symbol_referencer::staff_space (me
);
28 Real thick
= me
->paper_l ()->get_var ("stafflinethickness");
30 SCM s
= me
->get_grob_property ("line-thickness");
32 thick
*= gh_scm2double (s
);
34 // maybe these should be in line-thickness?
35 Real length
= staff_space
;
36 s
= me
->get_grob_property ("dash-length");
38 length
= gh_scm2double (s
) * staff_space
;
40 Real period
= 2 * length
+ thick
;
41 s
= me
->get_grob_property ("dash-period");
43 period
= gh_scm2double (s
) * staff_space
;
45 if (type
== ly_symbol2scm ("dotted-line"))
48 if (type
== ly_symbol2scm ("line"))
49 length
= period
+ thick
;
51 Real on
= length
- thick
;
52 Real off
= period
- on
;
54 list
= gh_list (ly_symbol2scm ("dashed-line"),
55 gh_double2scm (thick
),
66 Line_spanner::get_broken_offset (Grob
*me
, Direction dir
)
68 Spanner
*spanner
= dynamic_cast<Spanner
*> (me
);
69 Item
* bound
= spanner
->get_bound (dir
);
71 if (!bound
->break_status_dir ())
74 bound
->common_refpoint (Staff_symbol_referencer::staff_symbol_l (me
),
76 bound
->common_refpoint (Staff_symbol_referencer::staff_symbol_l (me
),
80 return Offset ( abs (bound
->extent (common
[X_AXIS
], X_AXIS
)[-dir
]),
81 bound
->extent (common
[Y_AXIS
], Y_AXIS
).center ());
87 Line_spanner::broken_trend_offset (Grob
*me
, Direction dir
)
89 /* A broken line-spaner should maintain the same vertical trend
90 the unbroken line-spanner would have had.
93 if (Spanner
*mother
= dynamic_cast<Spanner
*> (me
->original_l_
))
95 for (int i
= dir
== LEFT
? 0 : mother
->broken_into_l_arr_
.size () - 1;
96 dir
== LEFT
? i
< mother
->broken_into_l_arr_
.size () : i
> 0;
97 dir
== LEFT
? i
++ : i
--)
99 if (mother
->broken_into_l_arr_
[i
- dir
] == me
)
101 Grob
*neighbour
= mother
->broken_into_l_arr_
[i
];
102 Offset neighbour_o
= get_broken_offset (neighbour
, dir
);
103 Offset me_o
= get_broken_offset (me
, -dir
);
104 // Hmm, why not return me_o[X], but recalc in brew_mol?
106 (neighbour_o
[Y_AXIS
]*me_o
[X_AXIS
]
107 - me_o
[Y_AXIS
]*neighbour_o
[X_AXIS
]) * dir
/
108 (me_o
[X_AXIS
] + neighbour_o
[X_AXIS
]));
118 Warning: this thing is a cross-staff object, so it should have empty Y-dimensions.
120 (If not, you risk that this is called from the staff-alignment
121 routine, via molecule_extent. At this point, the staffs aren't
122 separated yet, so it doesn't work cross-staff.
126 MAKE_SCHEME_CALLBACK (Line_spanner
, brew_molecule
, 1);
128 Line_spanner::brew_molecule (SCM smob
)
130 Grob
*me
= unsmob_grob (smob
);
132 Spanner
*spanner
= dynamic_cast<Spanner
*> (me
);
133 Item
* bound_drul
[] = {
134 spanner
->get_bound (LEFT
),
136 spanner
->get_bound (RIGHT
)
139 Item
** bound
= bound_drul
+ 1;
141 Grob
*common
[] = { 0, 0 };
142 for (Axis a
= X_AXIS
; a
< NO_AXES
; a
= Axis (a
+ 1))
144 common
[a
] = bound
[LEFT
]->common_refpoint (bound
[RIGHT
], a
);
150 Real gap
= gh_scm2double (me
->get_grob_property ("gap"));
156 if (bound
[LEFT
]->break_status_dir () || bound
[RIGHT
]->break_status_dir ())
157 /* across line break */
159 Direction broken
= bound
[LEFT
]->break_status_dir () ? LEFT
: RIGHT
;
161 dxy
[X_AXIS
] = bound
[RIGHT
]->extent (common
[X_AXIS
], X_AXIS
)[LEFT
]
162 - bound
[LEFT
]->extent (common
[X_AXIS
], X_AXIS
)[RIGHT
];
164 dxy
+= broken_trend_offset (me
, broken
);
165 dxy
[X_AXIS
] -= 1 * gap
;
168 me
->relative_coordinate (common
[Y_AXIS
], Y_AXIS
));
171 bound
[-broken
]->relative_coordinate (common
[Y_AXIS
],
176 my_off
[Y_AXIS
] += dxy
[Y_AXIS
];
181 dxy
[X_AXIS
] = bound
[RIGHT
]->extent (common
[X_AXIS
], X_AXIS
)[LEFT
]
182 - bound
[LEFT
]->extent (common
[X_AXIS
], X_AXIS
)[RIGHT
];
183 dxy
[Y_AXIS
] = bound
[RIGHT
]->extent (common
[Y_AXIS
], Y_AXIS
).center ()
184 - bound
[LEFT
]->extent (common
[Y_AXIS
], Y_AXIS
).center ();
185 dxy
[X_AXIS
] -= 2 * gap
;
187 my_off
= Offset (me
->relative_coordinate (common
[X_AXIS
], X_AXIS
),
188 me
->relative_coordinate (common
[Y_AXIS
], Y_AXIS
));
190 his_off
= Offset (bound
[LEFT
]->relative_coordinate (common
[X_AXIS
],
192 bound
[LEFT
]->relative_coordinate (common
[Y_AXIS
],
197 SCM list
= Line_spanner::line_atom (me
, dxy
[X_AXIS
], dxy
[Y_AXIS
]);
202 Box
b (Interval (0, dxy
[X_AXIS
]), Interval (0, dxy
[Y_AXIS
]));
204 line
= Molecule (b
, list
);
205 line
.translate_axis (bound
[LEFT
]->extent (bound
[LEFT
], X_AXIS
).length (), X_AXIS
);
208 line
.translate (g
- my_off
+ his_off
);
210 return line
.smobbed_copy ();