]> git.donarmstrong.com Git - lilypond.git/blob - lily/system-start-text.cc
c99f150fed06fa75d476799244a671d9823f4bc3
[lilypond.git] / lily / system-start-text.cc
1 /*
2   system-start-text.cc -- implement System_start_text
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2006--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
7
8 */
9
10 #include "text-interface.hh"
11 #include "pointer-group-interface.hh"
12 #include "output-def.hh"
13 #include "font-interface.hh"
14 #include "spanner.hh"
15 #include "stencil.hh"
16 #include "item.hh"
17
18 class System_start_text
19 {
20 public:
21   static Stencil get_stencil (Grob *);
22   DECLARE_GROB_INTERFACE ();
23
24   DECLARE_SCHEME_CALLBACK (print, (SCM));
25 };
26
27 Stencil
28 System_start_text::get_stencil (Grob *me_grob)
29 {
30   Spanner *me = dynamic_cast<Spanner*> (me_grob);
31   SCM t = me->get_property ("text");
32   if (me->get_break_index () == 0)
33     t = me->get_property ("long-text");
34            
35   
36   SCM chain = Font_interface::text_font_alist_chain (me);
37
38   SCM scm_stencil = Text_interface::is_markup (t)
39     ? Text_interface::interpret_markup (me->layout ()->self_scm (), chain, t)
40     : SCM_EOL;
41
42   
43   if (Stencil *p = unsmob_stencil (scm_stencil))
44     {
45       SCM align_y  = me_grob->get_property ("self-alignment-Y");
46       if (scm_is_number (align_y))
47         p->align_to (Y_AXIS, robust_scm2double (align_y, 0.0));
48
49       /* Horizontal alignment according to the self-alignment-X property
50        * and indent value. */
51       Output_def *layout = me_grob->layout ();
52       Real indent;
53       if (me->get_break_index () == 0)
54         indent = robust_scm2double (layout->c_variable ("indent"), 0);
55       else
56         indent = robust_scm2double (layout->c_variable ("short-indent"), 0);
57       Real align_x = robust_scm2double (me->get_property ("self-alignment-X"), 0);
58       Interval p_extent_x = p->extent (X_AXIS);
59       Interval padding (0.0, max (0.0, indent - p_extent_x.length ()));
60       Real right_padding = padding.length () - padding.linear_combination (align_x);
61       Box box (Interval (p_extent_x[LEFT], p_extent_x[RIGHT] + right_padding),
62                p->extent (Y_AXIS));
63       Stencil *aligned_p = new Stencil (box, p->expr ());
64       return *aligned_p;
65     }
66   return Stencil ();
67 }
68
69
70 MAKE_SCHEME_CALLBACK (System_start_text, print, 1);
71 SCM
72 System_start_text::print (SCM smob)
73 {
74   Spanner *me = unsmob_spanner (smob);
75
76   if (!me->get_bound (LEFT)->break_status_dir ())
77     {
78       me->suicide ();
79       return SCM_EOL;
80     }
81
82   extract_grob_set (me, "elements", all_elts);
83   vector<Grob*> elts;
84   for (vsize i = 0; i < all_elts.size (); i++)
85     if (all_elts[i]->is_live ())
86       elts.push_back (all_elts[i]);
87
88   if (!elts.size ())
89     {
90       me->suicide ();
91       return SCM_EOL;
92     }
93   
94   Grob *common = common_refpoint_of_array (elts, me, Y_AXIS);
95
96   Interval ext;
97   for (vsize i = elts.size (); i--;)
98     {
99       Spanner *sp = dynamic_cast<Spanner *> (elts[i]);
100
101       if (sp
102           && sp->get_bound (LEFT) == me->get_bound (LEFT))
103         ext.add_point (sp->relative_coordinate (common, Y_AXIS));
104     }
105
106   Stencil m = get_stencil (me);
107   if (!ext.is_empty ())
108     m.translate_axis (ext.center (), Y_AXIS);
109   return m.smobbed_copy ();
110 }
111
112
113 ADD_INTERFACE (System_start_text,
114                "Text in front of the system.",
115
116                /* properties */
117                "text "
118                "long-text "
119                "self-alignment-Y "
120                "self-alignment-X "
121                );