]> git.donarmstrong.com Git - lilypond.git/blob - lily/self-aligment-interface.cc
* The grand 2005-2006 replace.
[lilypond.git] / lily / self-aligment-interface.cc
1 /*
2   self-alignment-interface.cc -- implement Self_alignment_interface
3  
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "self-alignment-interface.hh"
10 #include "warn.hh"
11
12 MAKE_SCHEME_CALLBACK (Self_alignment_interface, y_aligned_on_self, 1);
13 SCM
14 Self_alignment_interface::y_aligned_on_self (SCM element)
15 {
16   return aligned_on_self (unsmob_grob (element), Y_AXIS);
17 }
18
19 MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_aligned_on_self, 1);
20 SCM
21 Self_alignment_interface::x_aligned_on_self (SCM element)
22 {
23   return aligned_on_self (unsmob_grob (element), X_AXIS);
24 }
25
26 SCM
27 Self_alignment_interface::aligned_on_self (Grob *me, Axis a)
28 {
29   SCM sym = (a == X_AXIS) ? ly_symbol2scm ("self-alignment-X")
30     : ly_symbol2scm ("self-alignment-Y");
31
32   SCM align (me->internal_get_property (sym));
33   if (scm_is_number (align))
34     {
35       Interval ext (me->extent (me, a));
36       if (ext.is_empty ())
37         programming_error ("can't align on self: empty element");
38       else
39         return scm_from_double (- ext.linear_combination (scm_to_double (align)));
40     }
41   return scm_from_double (0.0);
42 }
43
44
45
46 SCM
47 Self_alignment_interface::centered_on_object (Grob *him, Axis a)
48 {
49   return scm_from_double (robust_relative_extent (him, him, a).center ());
50 }
51
52
53 MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_x_parent, 1);
54 SCM
55 Self_alignment_interface::centered_on_x_parent (SCM smob)
56 {
57   return centered_on_object (unsmob_grob (smob)->get_parent (X_AXIS), X_AXIS);
58 }
59
60
61 MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_y_parent, 1);
62 SCM
63 Self_alignment_interface::centered_on_y_parent (SCM smob)
64 {
65   return centered_on_object (unsmob_grob (smob)->get_parent (Y_AXIS), Y_AXIS);
66 }
67
68
69 MAKE_SCHEME_CALLBACK (Self_alignment_interface, x_centered_on_y_parent, 1);
70 SCM
71 Self_alignment_interface::x_centered_on_y_parent (SCM smob)
72 {
73   return centered_on_object (unsmob_grob (smob)->get_parent (Y_AXIS), X_AXIS);
74 }
75
76 MAKE_SCHEME_CALLBACK (Self_alignment_interface, aligned_on_x_parent,1);
77 SCM
78 Self_alignment_interface::aligned_on_x_parent (SCM smob)
79 {
80   return aligned_on_parent (unsmob_grob (smob), X_AXIS);
81 }
82
83 MAKE_SCHEME_CALLBACK (Self_alignment_interface, aligned_on_y_parent,1);
84 SCM
85 Self_alignment_interface::aligned_on_y_parent (SCM smob)
86 {
87   return aligned_on_parent (unsmob_grob (smob), Y_AXIS);
88 }
89
90 SCM
91 Self_alignment_interface::aligned_on_parent (Grob *me, Axis a)
92 {
93   Grob *him = me->get_parent (a);
94   Interval he = him->extent (him, a);
95
96   SCM sym = (a == X_AXIS) ? ly_symbol2scm ("self-alignment-X")
97     : ly_symbol2scm ("self-alignment-Y");
98   SCM align_prop (me->internal_get_property (sym));
99
100   if (!scm_is_number (align_prop))
101     return scm_from_int (0);
102
103   Real x = 0.0;
104   Real align = scm_to_double (align_prop);
105
106   Interval ext (me->extent (me, a));
107   if (ext.is_empty ())
108     programming_error ("can't align on self: empty element");
109   else
110     x -= ext.linear_combination (align);
111
112   if (!he.is_empty ())
113     x += he.linear_combination (align);
114
115   return scm_from_double (x);
116 }
117
118 void
119 Self_alignment_interface::set_center_parent (Grob *me, Axis a)
120 {
121   add_offset_callback (me,
122                        (a==X_AXIS) ? centered_on_x_parent_proc : centered_on_y_parent_proc,
123                        a);
124 }
125
126 void
127 Self_alignment_interface::set_align_self (Grob *me, Axis a)
128 {
129   add_offset_callback (me,
130                        (a==X_AXIS) ? x_aligned_on_self_proc : y_aligned_on_self_proc,
131                        a);
132 }
133
134 ADD_INTERFACE (Self_alignment_interface, "self-alignment-interface",
135                "Position this object on itself and/or on its parent. To this end, the following functions "
136                " are provided: \n"
137                "@table @code \n"
138                "@item Self_alignment_interface::[xy]_aligned_on_self\n"
139                "  Align self on reference point, using @code{self-alignment-X} and "
140                "@code{self-alignment-Y}."
141                "@item Self_alignment_interface::aligned_on_[xy]_parent\n"
142                "@item Self_alignment_interface::centered_on_[xy]_parent\n"
143                "  Shift the object so its own reference point is centered on the  "
144                " extent of the parent \n"
145                "@end table\n",
146
147
148                /* porperties */
149                "self-alignment-X "
150                "self-alignment-Y ");
151