]> git.donarmstrong.com Git - lilypond.git/blob - lily/encompass-info.cc
release: 1.1.54
[lilypond.git] / lily / encompass-info.cc
1 /*
2   encompass-info.cc -- implement Encompass_info
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1998--1999 Jan Nieuwenhuizen <janneke@gnu.org>
7
8 */
9
10 #include "proto.hh"
11 #include "stem.hh"
12 #include "note-column.hh"
13 #include "paper-def.hh"
14 #include "encompass-info.hh"
15 #include "slur.hh"
16 #include "staff-symbol.hh"
17 #include "note-head.hh"
18 #include "debug.hh"
19 #include "align-element.hh"
20
21 Encompass_info::Encompass_info ()
22 {
23   assert (0);
24 }
25
26 Encompass_info::Encompass_info (Note_column const* note, Direction dir, Slur const* slur_l)
27 {
28   interstaff_f_ = 0;
29   
30   Paper_def* paper = note->paper_l ();
31   
32   // UGH
33   Real notewidth = paper->note_width () * 0.8;
34   
35
36   Stem* stem_l = note->stem_l_;
37   if (!stem_l)
38     {
39       warning ("Slur over rest?");
40       o_[X_AXIS] = note->hpos_f ();
41       return; 
42     }
43   
44   Real internote = stem_l-> staff_line_leading_f ()/2.;
45
46   /* 
47     set o_[X_AXIS] to middle of notehead or on the exact position of stem,
48     according to slur direction
49    */
50   o_[X_AXIS] = stem_l->hpos_f ();
51
52   /*
53      stem_l->dir == dir
54                       ________
55            |   |     /        \
56           x|  x|       |x  |x
57         \________/     |   |
58
59    */
60
61   if (stem_l->dir_ != dir)
62     o_[X_AXIS] -= 0.5 * notewidth * stem_l->dir_;
63
64   o_[Y_AXIS] = stem_l->extent (Y_AXIS)[dir];
65   /*
66    leave a gap: slur mustn't touch head/stem
67    */
68   o_[Y_AXIS] += 2.5 * internote * dir;
69
70   if (stem_l->dir_ != dir)
71     o_[Y_AXIS] += 1.0 * internote * dir;
72
73
74   Dimension_cache *common = stem_l->common_group (slur_l, Y_AXIS);
75   Align_element * align = dynamic_cast<Align_element*> (common->element_l ());
76   if (align && align->axis() == Y_AXIS)
77     {
78       if (align->threshold_interval_[MIN] != 
79           align->threshold_interval_[MAX])
80         warning (_ ("minVerticalAlign != maxVerticalAlign: interstaff beams/slurs may be broken"));
81
82       interstaff_f_ = align->threshold_interval_[MIN];
83
84       Dimension_cache * slur_refpoint = slur_l->dim_cache_[Y_AXIS];
85       Dimension_cache * note_refpoint = note->dim_cache_[Y_AXIS];
86
87       while (slur_refpoint->parent_l_ != common)
88         slur_refpoint = slur_refpoint->parent_l_;
89       while (note_refpoint->parent_l_ != common)
90         note_refpoint = note_refpoint->parent_l_;
91
92
93       int slur_prio =
94         align->get_priority (dynamic_cast<Score_element*> (slur_refpoint->element_l ()));
95       int stem_prio =
96         align->get_priority (dynamic_cast<Score_element*> (note_refpoint->element_l ()));
97
98       /*
99         our staff is lower -> interstaff_f_ *= -1
100        */
101
102       if (slur_prio < stem_prio)
103         interstaff_f_ *= -1;
104       o_[Y_AXIS] += interstaff_f_;
105     }
106 }