]> git.donarmstrong.com Git - lilypond.git/blob - lily/stencil.cc
* scm/output-tex.scm: remove fontify; text and char take a font
[lilypond.git] / lily / stencil.cc
1 /*
2   stencil.cc -- implement Stencil
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include <math.h>
10 #include <libc-extension.hh>    // isinf
11
12 #include "font-metric.hh" 
13 #include "dimensions.hh"
14 #include "interval.hh"
15 #include "string.hh"
16 #include "stencil.hh"
17 #include "warn.hh"
18
19 #include "ly-smobs.icc"
20
21
22 Offset
23 Stencil::origin () const
24 {
25   return origin_;
26 }
27
28 Interval
29 Stencil::extent (Axis a) const
30 {
31   return dim_[a];
32 }
33
34 Stencil::Stencil (Box b, SCM func)
35 {
36   expr_ = func;
37   dim_ = b;
38 }
39
40 Stencil::Stencil ()
41 {
42   expr_ = SCM_EOL;
43   set_empty (true);
44 }
45
46 void
47 Stencil::translate (Offset o)
48 {
49   Axis a = X_AXIS;
50   while (a < NO_AXES)
51     {
52       if (abs (o[a]) > 100 CM
53           || isinf (o[a]) || isnan (o[a]))
54         {
55           programming_error ("Improbable offset for translation: setting to zero");
56           o[a] =  0.0;
57         }
58       incr (a);
59     }
60
61   expr_ = scm_list_n (ly_symbol2scm ("translate-stencil"),
62                       ly_offset2scm (o),
63                       expr_, SCM_UNDEFINED);
64   if (!is_empty ())
65     dim_.translate (o);
66   origin_ += o;
67 }
68   
69 void
70 Stencil::translate_axis (Real x, Axis a)
71 {
72   Offset o (0,0);
73   o[a] = x;
74   translate (o);
75 }
76
77 void
78 Stencil::add_stencil (Stencil const &s)
79 {
80   expr_ = scm_list_n (ly_symbol2scm ("combine-stencil"),
81                       s.expr_, expr_, SCM_UNDEFINED);
82   dim_.unite (s.dim_);
83 }
84
85 void
86 Stencil::set_empty (bool e)
87 {
88   if (e)
89     {
90       dim_[X_AXIS].set_empty ();
91       dim_[Y_AXIS].set_empty ();
92     }
93   else
94     {
95       dim_[X_AXIS] = Interval (0,0);
96       dim_[Y_AXIS] = Interval (0,0);
97     }
98 }
99
100 void
101 Stencil::align_to (Axis a, Real x)
102 {
103   if (is_empty ())
104     return ;
105
106   Interval i (extent (a));
107   translate_axis (-i.linear_combination (x), a);
108 }
109
110 /*
111   TODO: unintuitive naming, you would expect *this to be moved.  Kept
112   API for compat with add_at_edge ().
113 */
114 Stencil
115 Stencil::moved_to_edge (Axis a, Direction d, Stencil const &s, Real padding,
116                         Real minimum) const
117 {
118   Interval my_extent=  dim_[a];
119
120
121   Interval i (s.extent (a));
122   Real his_extent;
123   if (i.is_empty ())
124     {
125       programming_error ("Stencil::move_to_edge: adding empty stencil.");
126       his_extent = 0.0;
127     }
128   else
129     his_extent = i[-d];
130
131   Real offset = (my_extent.  is_empty () ? 0.0 : my_extent[d] - his_extent)
132     + d * padding;
133
134   Stencil toadd (s);
135   toadd.translate_axis (offset,a);
136
137   if (minimum > 0
138       && d *(- origin ()[a] + toadd.origin ()[a]) < minimum)
139     toadd.translate_axis ( -toadd.origin ()[a]
140                            + origin ()[a] + d* minimum, a);
141     
142   return toadd;
143 }
144
145 /*  See scheme Function.  */
146 void
147 Stencil::add_at_edge (Axis a, Direction d, Stencil const &s, Real padding,
148                       Real minimum)
149 {
150   add_stencil (moved_to_edge (a,d,s,padding, minimum));
151 }
152
153 /* Hmm... maybe this is not such a good idea ; stuff can be empty,
154    while expr_ == '()  */
155 bool
156 Stencil::is_empty () const
157 {
158   return expr_ == SCM_EOL;
159 }
160
161 SCM
162 Stencil::get_expr () const
163 {
164   return expr_;
165 }
166
167 Box
168 Stencil::extent_box () const
169 {
170   return dim_;
171 }
172
173 int
174 Stencil::print_smob (SCM , SCM port, scm_print_state *)
175 {
176   scm_puts ("#<Stencil ", port);
177   scm_puts (" >", port);
178   return 1;
179 }
180
181 SCM
182 Stencil::mark_smob (SCM s)
183 {
184   Stencil  *r = (Stencil *) ly_cdr (s);
185   return r->expr_;
186 }
187
188 IMPLEMENT_SIMPLE_SMOBS (Stencil);
189 IMPLEMENT_TYPE_P (Stencil, "ly:stencil?");
190 IMPLEMENT_DEFAULT_EQUAL_P (Stencil);