]> git.donarmstrong.com Git - lilypond.git/blob - lily/tex-beam.cc
release: 0.1.57
[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 #include "paper-def.hh"
23 #include "string-convert.hh"
24 #include "main.hh"
25
26 Atom
27 Lookup::beam_element (int sidx, int widx, Real slope) const
28 {
29   String name = String("slope");
30   Atom bs=(*symtables_p_)("beamslopes")->lookup (name);
31
32   Array<String> args;
33   args.push (sidx);
34   args.push (widx);
35   bs.tex_ = substitute_args (bs.tex_,args);
36   int w = 2 << widx;
37   Real width = w PT;
38   bs.dim_.x() = Interval (0,width);
39   bs.dim_.y() = Interval (0,width*slope);
40   return bs;
41 }
42
43
44 Atom
45 Lookup::rule_symbol (Real height, Real width) const
46 {
47   Atom bs=(*symtables_p_)("param")->lookup ("rule");
48   Array<String> args;
49   args.push (print_dimen (height));
50   args.push (print_dimen (width));
51   bs.tex_ = substitute_args (bs.tex_,args);
52   bs.dim_.x() = Interval (0,width);
53   bs.dim_.y() = Interval (0,height);
54   return bs;
55 }
56
57 Atom 
58 Lookup::beam(Real &slope, Real width, Real y_thick) const
59 {
60   Atom a( postscript_global_b
61           ? ps_beam (slope, width, y_thick)
62           : tex_beam (slope, width));
63   
64   Real slope_y =slope * width; 
65   Real min_y = (0 <? slope_y )- y_thick/2;
66   Real max_y = (0 >? slope_y) + y_thick/2;
67   
68   a.dim_[X_AXIS] = Interval(0, width);
69   a.dim_[Y_AXIS] = Interval(min_y, max_y);
70   return a;
71 }
72
73 Atom
74 Lookup::ps_beam (Real slope, Real width, Real y_thickness)const
75 {
76   String ps = "\\embeddedps{\n";
77   ps += String (width) + " "+ String (slope) + " " + String (y_thickness)
78     + " draw_beam}";
79
80   /* 
81    beam parts are rarely wider than 100pt: 
82    precision of 4 yields maximum (half beam spanning half a page)
83    error of: 1%% * 3*72pt === 0.2pt = 0.07mm
84    */
85   String width_str = String_convert::precision_str (width, 4);
86   String slope_str = String_convert::precision_str (slope, 4);
87   String thick_str = String_convert::precision_str (y_thickness, 3);
88   String name = "feta-beum-" + width_str + "-" + slope_str + "-" + thick_str;
89
90   int i;
91   while ((i = name.index_i ('.')) != -1)
92     name[i]=  'x';
93
94
95   String mf = "\\embeddedmf{" + name + "}{\n";
96   mf += "input feta-beum;\n";
97   mf += "drawbeam(" + width_str + "," + slope_str + "," + thick_str + ");\n";
98   mf += "end.\n";
99   mf += "}\n";
100
101   Atom s;
102   s.tex_ = ps;
103   if (embedded_mf_global_b)
104     s.tex_ += mf;
105   
106   return s;
107 }
108
109 Atom
110 Lookup::tex_beam (Real &slope, Real width) const
111 {
112   const Real MAX_SLOPE = 0.6;
113   const Real SLOPES = 20.0;
114   int sidx = 0;
115   if (abs (slope) > MAX_SLOPE)
116     {
117       WARN << _("beam too steep (") << slope << ")\n";
118       slope = sign (slope) * MAX_SLOPE;
119     }
120
121   sidx = int (rint (slope / MAX_SLOPE *  SLOPES));
122   slope = MAX_SLOPE * sidx / SLOPES;
123
124   Interval xdims = (*symtables_p_)("beamslopes")->lookup ("slope").dim_[X_AXIS];
125   Real min_wid = xdims[LEFT];
126   Real max_wid = xdims[RIGHT];
127   assert(max_wid > 0);
128   int widths = intlog2 (int (max_wid/min_wid)) + 1;
129
130   if (width < min_wid)
131     {
132       WARN<<_("Beam too narrow. (") << print_dimen (width) <<")\n";
133       width = min_wid;
134     }
135
136   Real elemwidth = max_wid;
137
138   int widx  =widths - 1;
139   Molecule m;
140   while (elemwidth > width)
141     {
142       widx --;
143       elemwidth /= 2.0;
144     }
145   Real overlap = elemwidth/4;
146   Real last_x = width - elemwidth;
147   Real x = overlap;
148   Atom elem (beam_element (sidx * widths, widx, slope));
149   m.add (elem);
150   while (x < last_x)
151     {
152       Atom a(elem);
153       a.translate (Offset (x-overlap, (x-overlap)*slope));
154       m.add (a);
155       x += elemwidth - overlap;
156     }
157   Atom a(elem);
158   a.translate (Offset (last_x, (last_x) * slope));
159   m.add (a);
160
161   Atom ret;
162   ret.tex_ = m.TeX_string();
163
164   return ret;
165 }