]> git.donarmstrong.com Git - lilypond.git/blob - lily/tex-beam.cc
release: 0.1.17
[lilypond.git] / lily / tex-beam.cc
1 /*
2   tex-beam.cc -- implement Lookup::{beam_element, beam, rule_symbol}
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1996,1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 /*
10   Code to generate beams for TeX
11   */
12
13 #include <math.h>
14 #include "atom.hh"
15 #include "molecule.hh"
16 #include "tex.hh"
17 #include "symtable.hh"
18 #include "dimen.hh"
19 #include "debug.hh"
20 #include "lookup.hh"
21 #include "misc.hh"
22
23 Atom
24 Lookup::beam_element (int sidx, int widx, Real slope) const
25 {
26   char dir_char = slope >0 ? 'u' : 'd';
27   String name = dir_char + String("slope");
28   Atom bs=(*symtables_)("beamslopes")->lookup (name);
29   
30   Array<String> args;
31   args.push (sidx);
32   args.push (widx);
33   bs.tex_ = substitute_args (bs.tex_,args);
34   int w = 2 << widx;
35   Real width = w PT;
36   bs.dim_.x() = Interval (0,width);
37   bs.dim_.y() = Interval (0,width*slope);
38   return bs;
39 }
40
41 // ugh.. hard wired tex-code.
42 static int
43 slope_index (Real &s)
44 {
45   if (abs (s) > 0.5)
46     {
47       WARN << "beam steeper than 0.5 (" << s << ")\n";
48       s = sign (s) * 0.5;
49     }
50
51   int i = int (rint (s *  20.0));
52
53   s = i/20.0;
54   if (s>0)
55     return 6*i;
56   else
57     return -6 * i;
58 }
59
60 Atom
61 Lookup::rule_symbol (Real height, Real width) const
62 {
63   Atom bs=(*symtables_)("beamslopes")->lookup ("horizontal");    
64   Array<String> args;
65   args.push (print_dimen (height));
66   args.push (print_dimen (width));
67   bs.tex_ = substitute_args (bs.tex_,args);
68   bs.dim_.x() = Interval (0,width);
69   bs.dim_.y() = Interval (0,height);
70   return bs;
71 }
72
73 Atom
74 Lookup::beam (Real &slope, Real width) const
75 {        
76   int sidx = slope_index (slope);
77   if (!slope)
78     return rule_symbol (2 PT, width);
79
80   Interval xdims = (*symtables_)("beamslopes")->lookup ("uslope").dim_[X_AXIS];
81   Real min_wid = xdims[LEFT];
82   Real max_wid = xdims[RIGHT];
83
84   if (width < min_wid) 
85     {
86       WARN<<"Beam too narrow. (" << print_dimen (width) <<")\n";
87       width = min_wid;
88     }
89   Real elemwidth = max_wid;
90   int widx = intlog2 (int (max_wid/min_wid));
91
92   Molecule m;
93   
94   while (elemwidth > width) 
95     {
96       widx --;
97       elemwidth /= 2.0;
98     }
99   Real overlap = elemwidth/4;
100   Real last_x = width - elemwidth;
101   Real x = overlap;
102   Atom elem (beam_element (sidx, widx, slope));
103   m.add (elem);
104   while (x < last_x) 
105     {
106       Atom a(elem);
107       a.translate (Offset (x-overlap, (x-overlap)*slope));
108       m.add (a);
109       x += elemwidth - overlap;
110     }
111   Atom a(elem);
112   a.translate (Offset (last_x, (last_x) * slope));
113   m.add (a);
114   
115   Atom ret;
116   ret.tex_ = m.TeX_string();
117   ret.dim_.y() = Interval (0,width*slope);
118   ret.dim_.x() = Interval (0,width);
119   
120   return ret;
121 }
122
123