]> git.donarmstrong.com Git - lilypond.git/blob - lily/tex-beam.cc
release: 0.1.39
[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 "main.hh"
23
24 Atom
25 Lookup::beam_element (int sidx, int widx, Real slope) const
26 {
27   String name = String("slope");
28   Atom bs=(*symtables_p_)("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
42 Atom
43 Lookup::rule_symbol (Real height, Real width) const
44 {
45   Atom bs=(*symtables_p_)("beamslopes")->lookup ("horizontal");
46   Array<String> args;
47   args.push (print_dimen (height));
48   args.push (print_dimen (width));
49   bs.tex_ = substitute_args (bs.tex_,args);
50   bs.dim_.x() = Interval (0,width);
51   bs.dim_.y() = Interval (0,height);
52   return bs;
53 }
54
55 Atom 
56 Lookup::beam(Real &slope, Real width, Real y_thick) const
57 {
58   if (postscript_global_b)
59     {
60       return ps_beam (slope, width, y_thick);
61     }
62   else
63     return tex_beam(slope, width);
64 }
65
66 Atom
67 Lookup::ps_beam (Real  slope, Real width, Real y_thickness)const
68 {
69   Atom ret;
70   String ps(String (width) + " "+ String(slope) 
71             + " " + String(y_thickness) + " draw_beam");
72   ret.tex_ = String("\\embeddedps{" + ps + "}");
73   ret.dim_[X_AXIS] = Interval(0, width);
74   ret.dim_[Y_AXIS] = Interval(0, slope * width + y_thickness);
75   return ret;
76 }
77
78 Atom
79 Lookup::tex_beam (Real &slope, Real width) const
80 {
81   const Real MAX_SLOPE = 0.6;
82   const Real SLOPES = 20.0;
83   int sidx = 0;
84   if (abs (slope) > MAX_SLOPE)
85     {
86       WARN << _("beam too steep (") << slope << ")\n";
87       slope = sign (slope) * MAX_SLOPE;
88     }
89
90   sidx = int (rint (slope / MAX_SLOPE *  SLOPES));
91   slope = MAX_SLOPE * sidx / SLOPES;
92
93   Interval xdims = (*symtables_p_)("beamslopes")->lookup ("slope").dim_[X_AXIS];
94   Real min_wid = xdims[LEFT];
95   Real max_wid = xdims[RIGHT];
96   assert(max_wid > 0);
97   int widths = intlog2 (int (max_wid/min_wid)) + 1;
98
99   if (width < min_wid)
100     {
101       WARN<<_("Beam too narrow. (") << print_dimen (width) <<")\n";
102       width = min_wid;
103     }
104
105   Real elemwidth = max_wid;
106
107   int widx  =widths - 1;
108   Molecule m;
109   while (elemwidth > width)
110     {
111       widx --;
112       elemwidth /= 2.0;
113     }
114   Real overlap = elemwidth/4;
115   Real last_x = width - elemwidth;
116   Real x = overlap;
117   Atom elem (beam_element (sidx * widths, widx, slope));
118   m.add (elem);
119   while (x < last_x)
120     {
121       Atom a(elem);
122       a.translate (Offset (x-overlap, (x-overlap)*slope));
123       m.add (a);
124       x += elemwidth - overlap;
125     }
126   Atom a(elem);
127   a.translate (Offset (last_x, (last_x) * slope));
128   m.add (a);
129
130   Atom ret;
131   ret.tex_ = m.TeX_string();
132   ret.dim_.y() = Interval (0,width*slope);
133   ret.dim_.x() = Interval (0,width);
134
135   return ret;
136 }