+1.3.64.jcn2
+============
+
+* Made slur attachment position user settable; properties:
+slurBeginAttachment slurEndAttachment, values: 'head 'stem
+'along-side-stem. See input/test/slur-attachment.ly and ophee-slurs.ly.
+
+* Fixed slur attachment positions, added missing rule and use simple
+default starting positions for attachments.
+
+
1.3.63.jcn1
============
MAJOR_VERSION=1
MINOR_VERSION=3
PATCH_LEVEL=64
-MY_PATCH_LEVEL=jcn1
+MY_PATCH_LEVEL=jcn2
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
--- /dev/null
+\score{
+ \notes \relative c''{
+ \property Voice.slurVerticalDirection = #1 c8(()c())c4
+ \property Voice.slurVerticalDirection = #-1 a8(()a)a4
+ \break
+
+ \property Voice.slurVerticalDirection = #-1 a8(()a())a4
+ \property Voice.slurVerticalDirection = #1 c8(()c)c4
+ \break
+
+ \property Voice.slurVerticalDirection = #-1 e8(()e())e4
+ \property Voice.slurVerticalDirection = #1 f,8(()f)f4
+ \break
+
+ \property Voice.slurVerticalDirection = #1 e8(()e())e4
+ \property Voice.slurVerticalDirection = #-1 f'8(()f)f4
+ \break
+
+ }
+ \paper{
+ indent = 0.0;
+ linewidth = 60.0\mm;
+ }
+}
--- /dev/null
+\score{
+ \notes \relative c''{
+ \property Voice.slurVerticalDirection = #1
+ \property Voice.slurBeginAttachment = #'head
+ \property Voice.slurEndAttachment = #'head
+ g16()g()g()g()d'()d()d()d
+ }
+ \paper{
+ indent = 0.0;
+ linewidth = 60.0\mm;
+ }
+}
--- /dev/null
+\score{
+ \notes \relative c''{
+ \property Voice.slurVerticalDirection = #1 c()a d()g,\break
+ \property Voice.slurVerticalDirection = #-1 c()a d()g,\break
+ \property Voice.slurVerticalDirection = #1 a()c d()g,\break
+ \property Voice.slurVerticalDirection = #-1 a()c d()g,\break
+ \property Voice.slurVerticalDirection = #-1 a()c d()g,\break
+ }
+ \paper{
+ indent = 0.0;
+ linewidth = 60.0\mm;
+ }
+}
--- /dev/null
+\score{
+ \notes \relative c''{
+ % URG, make stem length match beam!
+ \property Voice.stemLength = #5
+
+ \property Voice.slurVerticalDirection = #1
+ \property Voice.slurEndAttachment = #'stem
+ a8(a)a4
+ \property Voice.slurEndAttachment = ##f
+ \property Voice.slurBeginAttachment = #'stem
+ a4(a8)a
+ }
+ \paper{
+ indent = 0.0;
+ linewidth = 60.0\mm;
+ }
+}
void set_melisma (bool);
protected:
virtual bool do_try_music (Music*);
- virtual void do_process_music();
+ virtual void do_process_music ();
virtual void acknowledge_element (Score_element_info);
- virtual void do_pre_move_processing();
- virtual void do_post_move_processing();
+ virtual void do_pre_move_processing ();
+ virtual void do_post_move_processing ();
virtual void do_removal_processing ();
public:
- VIRTUAL_COPY_CONS(Translator);
+ VIRTUAL_COPY_CONS (Translator);
};
if (dynamic_cast<Note_column *> (info.elem_l_))
{
Note_column *col_l =dynamic_cast<Note_column *> (info.elem_l_) ;// ugh
- for (int i = 0; i < slur_l_stack_.size(); i++)
+ for (int i = 0; i < slur_l_stack_.size (); i++)
slur_l_stack_[i]->add_column (col_l);
- for (int i = 0; i < end_slur_l_arr_.size(); i++)
+ for (int i = 0; i < end_slur_l_arr_.size (); i++)
end_slur_l_arr_[i]->add_column (col_l);
}
}
void
Slur_engraver::do_removal_processing ()
{
- for (int i = 0; i < slur_l_stack_.size(); i++)
+ for (int i = 0; i < slur_l_stack_.size (); i++)
{
typeset_element (slur_l_stack_[i]);
}
SCM wg = get_property ("weAreGraceContext");
bool wgb = to_boolean (wg);
if (!wgb)
- for (int i=0; i < requests_arr_.size(); i++)
+ for (int i=0; i < requests_arr_.size (); i++)
{
requests_arr_[i]->warning (_ ("unterminated slur"));
}
}
void
-Slur_engraver::do_process_music()
+Slur_engraver::do_process_music ()
{
Array<Slur*> start_slur_l_arr_;
- for (int i=0; i< new_slur_req_l_arr_.size(); i++)
+ for (int i=0; i< new_slur_req_l_arr_.size (); i++)
{
Span_req* slur_req_l = new_slur_req_l_arr_[i];
// end slur: move the slur to other array
if (slur_req_l->span_dir_ == STOP)
{
- if (slur_l_stack_.empty())
+ if (slur_l_stack_.empty ())
- slur_req_l->warning (_f ("can't find both ends of %s", _("slur")));
+ slur_req_l->warning (_f ("can't find both ends of %s", _ ("slur")));
else
{
- end_slur_l_arr_.push (slur_l_stack_.pop());
- requests_arr_.pop();
+ Slur* slur = slur_l_stack_.pop ();
+ SCM s = get_property ("slurEndAttachment");
+ if (gh_symbol_p (s))
+ {
+ index_set_cell (slur->get_elt_property ("attachment"), STOP, s);
+ }
+ end_slur_l_arr_.push (slur);
+ requests_arr_.pop ();
}
}
else if (slur_req_l->span_dir_ == START)
{
// push a new slur onto stack.
- //(use temp. array to wait for all slur STOPs)
- Slur * s_p =new Slur (get_property ("basicSlurProperties"));
-
+ // (use temp. array to wait for all slur STOPs)
+ Slur* slur = new Slur (get_property ("basicSlurProperties"));
+ SCM s = get_property ("slurBeginAttachment");
+ if (gh_symbol_p (s))
+ {
+ index_set_cell (slur->get_elt_property ("attachment"), START, s);
+ }
+ start_slur_l_arr_.push (slur);
requests_arr_.push (slur_req_l);
- start_slur_l_arr_.push (s_p);
- announce_element (Score_element_info (s_p, slur_req_l));
+ announce_element (Score_element_info (slur, slur_req_l));
}
}
- for (int i=0; i < start_slur_l_arr_.size(); i++)
+ for (int i=0; i < start_slur_l_arr_.size (); i++)
slur_l_stack_.push (start_slur_l_arr_[i]);
}
void
-Slur_engraver::do_pre_move_processing()
+Slur_engraver::do_pre_move_processing ()
{
- for (int i = 0; i < end_slur_l_arr_.size(); i++)
+ for (int i = 0; i < end_slur_l_arr_.size (); i++)
{
typeset_element (end_slur_l_arr_[i]);
}
- end_slur_l_arr_.clear();
+ end_slur_l_arr_.clear ();
}
void
-Slur_engraver::do_post_move_processing()
+Slur_engraver::do_post_move_processing ()
{
- new_slur_req_l_arr_.clear();
+ new_slur_req_l_arr_.clear ();
SCM m = get_property ("automaticMelismata");
if (to_boolean (m))
{
}
-ADD_THIS_TRANSLATOR(Slur_engraver);
+ADD_THIS_TRANSLATOR (Slur_engraver);
[TODO]
* begin and end should be treated as a/acknowledge Scripts.
* broken slur should have uniform trend
+ * smart changing of endings and offsets to avoid ugly beziers.
*/
#include "directional-element-interface.hh"
Slur::Slur (SCM s)
: Spanner (s)
{
- /*
- silly value for testing
- */
- set_elt_property ("attachment", gh_cons (ly_symbol2scm ("alongside-stem"),
- ly_symbol2scm ("alongside-stem")));
+ set_elt_property ("attachment", gh_cons (SCM_BOOL_F, SCM_BOOL_F));
set_elt_pointer ("note-columns", SCM_EOL);
set_elt_property ("control-points", SCM_EOL);
}
Direction dir = LEFT;
do
{
- // for (SCM s = get_elt_property ("slur-extremity-rules"); s != SCM_EOL; s = gh_cdr (s))
- for (SCM s = scm_eval (ly_symbol2scm ("slur-extremity-rules"));
- s != SCM_EOL; s = gh_cdr (s))
+ if (!gh_symbol_p (index_cell (get_elt_property ("attachment"), dir)))
{
- SCM r = scm_eval (scm_listify (gh_caar (s),
- this->self_scm_,
- gh_int2scm ((int)dir),
- SCM_UNDEFINED));
- if (r != SCM_BOOL_F)
+
+ // for (SCM s = get_elt_property ("slur-extremity-rules"); s != SCM_EOL; s = gh_cdr (s))
+ for (SCM s = scm_eval (ly_symbol2scm ("slur-extremity-rules"));
+ s != SCM_EOL; s = gh_cdr (s))
{
- index_set_cell (get_elt_property ("attachment"), dir,
- gh_cdar (s));
- break;
+ SCM r = scm_eval (scm_listify (gh_caar (s),
+ this->self_scm_,
+ gh_int2scm ((int)dir),
+ SCM_UNDEFINED));
+ if (r != SCM_BOOL_F)
+ {
+ index_set_cell (get_elt_property ("attachment"), dir,
+ gh_cdar (s));
+ break;
+ }
}
}
}
if (str == "head")
{
o = Offset (0, st->chord_start_f ());
+ /*
+ Default position is centered in X, on outer side of head Y
+ */
+ o += Offset (0.5 * n->extent (X_AXIS).length (),
+ 0.5 * ss * directional_element (this).get ());
}
else if (str == "alongside-stem")
{
o = Offset (0, st->chord_start_f ());
+ /*
+ Default position is on stem X, on outer side of head Y
+ */
+ o += Offset (n->extent (X_AXIS).length ()
+ * (1 + st->get_direction ()),
+ 0.5 * ss * directional_element (this).get ());
}
else if (str == "stem")
{
o = Offset (0, st->stem_end_position () * hs);
+ /*
+ Default position is on stem X, at stem end Y
+ */
+ o += Offset (0.5 *
+ (n->extent (X_AXIS).length ()
+ - st->extent (X_AXIS).length ())
+ * (1 + st->get_direction ()),
+ 0);
}
else if (str == "loose-end")
{
}
}
- o += Offset (0.5 * st->get_direction ()
- * n->extent (X_AXIS).length (), 0);
SCM l = scm_assoc
(scm_listify (a,
(define slur-extremity-rules
'(
- ;;if (stem_l->beam_l () && (stem_l->beam_count (-d) >= 1))
((lambda (slur dir)
;; urg, code dup
- ;; if attached-to-stem
(let* ((note-columns (get-pointer slur 'note-columns))
(col (if (= dir 1) (car note-columns) (car (reverse note-columns))))
(stem (get-pointer col 'stem)))
- (and
- (and
- (eq? col (get-bound slur dir))
- stem
- (get-pointer stem 'heads))
- ;; and got beam
- (and (get-pointer stem 'beam)
- ;; and beam on same side as slur
- (let ((beaming (get-property stem 'beaming)))
- (if (pair? beaming)
- (>= 1
- (if (= dir -1) (car beaming) (cdr beaming)))
- #f)))))) . stem)
+ (and stem
+ (not (= (get-property slur 'direction)
+ (get-property stem 'direction)))))) . head)
+
+ ((lambda (slur dir)
+ ;; if attached-to-stem
+ (and (attached-to-stem slur dir)
+ ;; and got beam
+ ;; urg, code dup
+ (let* ((note-columns (get-pointer slur 'note-columns))
+ (col (if (= dir 1) (car note-columns) (car (reverse note-columns))))
+ (stem (get-pointer col 'stem)))
+ (and stem
+ (get-pointer stem 'beam)
+ ;; and beam on same side as slur
+ (let ((beaming (get-property stem 'beaming)))
+ (if (pair? beaming)
+ (>= 1
+ (if (= dir -1) (car beaming) (cdr beaming)))
+ #f)))))) . stem)
+
((lambda (slur dir) (not (attached-to-stem slur dir))) . loose-end)
+
;; default case, attach to head
((lambda (x y) #t) . head)
- ;; silly rule, just to check
- ((lambda (slur dir)
+ ;; silly rule, just to check
+ ((lambda (slur dir)
(and (attached-to-stem slur dir)
(= (get-property slur 'direction) dir))) . stem)
- ))
+ ))
(define slur-extremity-offset-alist
'(
((head 1 1) . (-0.25 . 0.2))
- ((head 1 -1) . (-0.25 . -0.75))
- ((head -1 1) . (-0.25 . 0.75))
- ((head -1 -1) . (-0.75 . 1.2))
- ((stem 1 1) . (0 . 0.2))
- ((stem -1 -1) . (0 . 0.2))
+ ((head 1 -1) . (-0.25 . -0.25))
+ ((head -1 1) . (-0.25 . 0.25))
+ ((head -1 -1) . (-0.85 . -0.2))
+
+ ((stem 1 1) . (0 . 0.5))
+ ((stem -1 -1) . (0 . -0.5))
))