LEFT | RIGHT |
1 /* | 1 /* |
2 This file is part of LilyPond, the GNU music typesetter. | 2 This file is part of LilyPond, the GNU music typesetter. |
3 | 3 |
4 Copyright (C) 2004--2012 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 2004--2012 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 | 5 |
6 LilyPond is free software: you can redistribute it and/or modify | 6 LilyPond is free software: you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation, either version 3 of the License, or | 8 the Free Software Foundation, either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... |
26 #include "note-column.hh" | 26 #include "note-column.hh" |
27 #include "paper-column.hh" | 27 #include "paper-column.hh" |
28 #include "pointer-group-interface.hh" | 28 #include "pointer-group-interface.hh" |
29 #include "warn.hh" | 29 #include "warn.hh" |
30 | 30 |
31 MAKE_SCHEME_CALLBACK (Self_alignment_interface, y_aligned_on_self, 1); | 31 MAKE_SCHEME_CALLBACK (Self_alignment_interface, y_aligned_on_self, 1); |
32 SCM | 32 SCM |
33 Self_alignment_interface::y_aligned_on_self (SCM element) | 33 Self_alignment_interface::y_aligned_on_self (SCM element) |
34 { | 34 { |
35 Grob *me = unsmob_grob (element); | 35 Grob *me = unsmob_grob (element); |
36 return align_grob (me, NULL, get_alignment (me, Y_AXIS), Y_AXIS, false, 0, 0); | 36 return align_grob (me, NULL, Y_AXIS, false, 0, 0); |
37 } | 37 } |
38 | 38 |
39 MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_aligned_on_self, 1); | 39 MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_aligned_on_self, 1); |
40 SCM | 40 SCM |
41 Self_alignment_interface::x_aligned_on_self (SCM element) | 41 Self_alignment_interface::x_aligned_on_self (SCM element) |
42 { | 42 { |
43 Grob *me = unsmob_grob (element); | 43 Grob *me = unsmob_grob (element); |
44 return align_grob (me, NULL, get_alignment (me, X_AXIS), X_AXIS, false, 0, 0); | 44 return align_grob (me, NULL, X_AXIS, false, 0, 0); |
45 } | 45 } |
46 | 46 |
47 MAKE_SCHEME_CALLBACK (Self_alignment_interface, pure_y_aligned_on_self, 3); | 47 MAKE_SCHEME_CALLBACK (Self_alignment_interface, pure_y_aligned_on_self, 3); |
48 SCM | 48 SCM |
49 Self_alignment_interface::pure_y_aligned_on_self (SCM smob, SCM start, SCM end) | 49 Self_alignment_interface::pure_y_aligned_on_self (SCM smob, SCM start, SCM end) |
50 { | 50 { |
51 Grob *me = unsmob_grob (smob); | 51 Grob *me = unsmob_grob (smob); |
52 return align_grob (me, NULL, get_alignment (me, Y_AXIS), Y_AXIS, true, robust_
scm2int (start, 0), robust_scm2int (end, INT_MAX)); | 52 return align_grob (me, NULL, Y_AXIS, true, robust_scm2int (start, 0), robust_s
cm2int (end, INT_MAX)); |
| 53 } |
| 54 |
| 55 SCM |
| 56 Self_alignment_interface::centered_on_object (Grob *him, Axis a) |
| 57 { |
| 58 return scm_from_double (robust_relative_extent (him, him, a).center ()); |
53 } | 59 } |
54 | 60 |
55 MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_x_parent, 1); | 61 MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_x_parent, 1); |
56 SCM | 62 SCM |
57 Self_alignment_interface::centered_on_x_parent (SCM smob) | 63 Self_alignment_interface::centered_on_x_parent (SCM smob) |
58 { | 64 { |
59 Grob *me = unsmob_grob (smob); | 65 return centered_on_object (unsmob_grob (smob)->get_parent (X_AXIS), X_AXIS); |
60 return align_grob (NULL, me->get_parent (X_AXIS), scm_from_double (0), X_AXIS,
false, 0, 0); | |
61 } | 66 } |
62 | 67 |
63 MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_y_parent, 1); | 68 MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_y_parent, 1); |
64 SCM | 69 SCM |
65 Self_alignment_interface::centered_on_y_parent (SCM smob) | 70 Self_alignment_interface::centered_on_y_parent (SCM smob) |
66 { | 71 { |
67 Grob *me = unsmob_grob (smob); | 72 return centered_on_object (unsmob_grob (smob)->get_parent (Y_AXIS), Y_AXIS); |
68 return align_grob (NULL, me->get_parent (Y_AXIS), scm_from_double (0), Y_AXIS,
false, 0, 0); | |
69 } | 73 } |
70 | 74 |
71 MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_centered_on_y_parent, 1); | 75 MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_centered_on_y_parent, 1); |
72 SCM | 76 SCM |
73 Self_alignment_interface::x_centered_on_y_parent (SCM smob) | 77 Self_alignment_interface::x_centered_on_y_parent (SCM smob) |
74 { | 78 { |
75 Grob *me = unsmob_grob (smob); | 79 return centered_on_object (unsmob_grob (smob)->get_parent (Y_AXIS), X_AXIS); |
76 return align_grob (NULL, me->get_parent (Y_AXIS), scm_from_double (0), X_AXIS,
false, 0, 0); | |
77 } | 80 } |
78 | 81 |
79 MAKE_SCHEME_CALLBACK (Self_alignment_interface, aligned_on_x_parent, 1); | 82 MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_align_grob, 1); |
80 SCM | 83 SCM |
81 Self_alignment_interface::aligned_on_x_parent (SCM smob) | 84 Self_alignment_interface::x_align_grob (SCM smob) |
82 { | 85 { |
83 Grob *me = unsmob_grob (smob); | 86 Grob *me = unsmob_grob (smob); |
84 return align_grob (me, me->get_parent (X_AXIS), get_alignment (me, X_AXIS), X_
AXIS, false, 0, 0); | 87 return align_grob (me, me->get_parent (X_AXIS), X_AXIS, false, 0, 0); |
85 } | 88 } |
86 | 89 |
87 MAKE_SCHEME_CALLBACK (Self_alignment_interface, aligned_on_y_parent, 1); | 90 MAKE_SCHEME_CALLBACK (Self_alignment_interface, y_align_grob, 1); |
88 SCM | 91 SCM |
89 Self_alignment_interface::aligned_on_y_parent (SCM smob) | 92 Self_alignment_interface::y_align_grob (SCM smob) |
90 { | 93 { |
91 Grob *me = unsmob_grob (smob); | 94 Grob *me = unsmob_grob (smob); |
92 return align_grob (me, me->get_parent (Y_AXIS), get_alignment (me, Y_AXIS), Y_
AXIS, false, 0, 0); | 95 return align_grob (me, me->get_parent (Y_AXIS), Y_AXIS, false, 0, 0); |
93 } | |
94 | |
95 /* | |
96 This is not a part of align_grob because we might be unable to fetch | |
97 required properties there ('me' sometimes is a null pointer inside align_grob)
. | |
98 */ | |
99 SCM | |
100 Self_alignment_interface::get_alignment (Grob *me, Axis a) | |
101 { | |
102 return (a == X_AXIS) | |
103 ? me->internal_get_property (ly_symbol2scm ("self-alignment-X")) | |
104 : me->internal_get_property (ly_symbol2scm ("self-alignment-Y")); | |
105 } | 96 } |
106 | 97 |
107 /* | 98 /* |
108 Positioning of grobs is done relative to their parents in respective axes. | 99 Positioning of grobs is done relative to their parents in respective axes. |
109 Grob properties [XY]-offset measure the displacement between grob's reference | 100 Grob properties [XY]-offset measure the displacement between grob's reference |
110 point and the reference point of grob's parent in [XY]_AXIS (in staffspaces). | 101 point and the reference point of grob's parent in [XY]_AXIS (in staffspaces). |
111 | 102 |
112 To align a particular point of the grob with a particular point of its parent | 103 To align a particular point of the grob with a particular point of its parent |
113 one has to calculate what this offset should be, based on dimensions (extents) | 104 one has to calculate what this offset should be, based on dimensions (extents) |
114 of both objects. | 105 of both objects. |
115 */ | 106 */ |
116 SCM | 107 SCM |
117 Self_alignment_interface::align_grob (Grob *me, | 108 Self_alignment_interface::align_grob (Grob *me, |
118 Grob *him, | 109 Grob *him, |
119 SCM alignment, | |
120 Axis a, | 110 Axis a, |
121 bool pure, | 111 bool pure, |
122 int start, | 112 int start, |
123 int end) | 113 int end) |
124 { | 114 { |
125 Real offset = 0.0; | 115 Real offset = 0.0; |
| 116 |
| 117 SCM alignment = (a == X_AXIS) |
| 118 ? me->internal_get_property (ly_symbol2scm ("self-alignment-X"
)) |
| 119 : me->internal_get_property (ly_symbol2scm ("self-alignment-Y"
)); |
126 | 120 |
127 SCM my_alignment, his_alignment; | 121 SCM my_alignment, his_alignment; |
128 if (scm_is_pair (alignment)) | 122 if (scm_is_pair (alignment)) |
129 { | 123 { |
130 my_alignment = scm_car (alignment); | 124 my_alignment = scm_car (alignment); |
131 his_alignment = scm_cdr (alignment); | 125 his_alignment = scm_cdr (alignment); |
132 } | 126 } |
133 else | 127 else |
134 { | 128 { |
135 my_alignment = alignment; | 129 my_alignment = alignment; |
136 his_alignment = alignment; | 130 his_alignment = alignment; |
137 } | 131 } |
138 | 132 |
139 // calculate offset related to grob's own dimensions | 133 // calculate offset related to grob's own dimensions |
140 if (me && scm_is_number (my_alignment)) | 134 if (scm_is_number (my_alignment)) |
141 { | 135 { |
142 Interval my_ext = me->maybe_pure_extent (me, a, pure, start, end); | 136 Interval my_ext = me->maybe_pure_extent (me, a, pure, start, end); |
143 | 137 |
144 // Empty extent doesn't mean an error - we simply don't align such grobs. | 138 // Empty extent doesn't mean an error - we simply don't align such grobs. |
145 // However, empty extent and non-empty stencil would be suspicious. | 139 // However, empty extent and non-empty stencil would be suspicious. |
146 if (!my_ext.is_empty ()) | 140 if (!my_ext.is_empty ()) |
147 offset -= my_ext.linear_combination (scm_to_double (my_alignment)); | 141 offset -= my_ext.linear_combination (scm_to_double (my_alignment)); |
148 else if (me->get_stencil ()) | 142 else if (me->get_stencil ()) |
149 warning (me->name () + " has empty extent and non-empty stencil."); | 143 warning (me->name () + " has empty extent and non-empty stencil."); |
150 } | 144 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 | 181 |
188 /* properties */ | 182 /* properties */ |
189 "collision-bias " | 183 "collision-bias " |
190 "collision-padding " | 184 "collision-padding " |
191 "potential-X-colliding-grobs " | 185 "potential-X-colliding-grobs " |
192 "self-alignment-X " | 186 "self-alignment-X " |
193 "self-alignment-Y " | 187 "self-alignment-Y " |
194 "X-colliding-grobs " | 188 "X-colliding-grobs " |
195 "Y-colliding-grobs " | 189 "Y-colliding-grobs " |
196 ); | 190 ); |
LEFT | RIGHT |