*/
#include <math.h>
+#include "main.hh"
#include "misc.hh"
#include "lookup.hh"
#include "molecule.hh"
#include "dimen.hh"
#include "debug.hh"
#include "paper-def.hh"
+#include "string-convert.hh"
-
-static
-char direction_char(int y_sign)
+static char
+direction_char (Direction y_sign)
{
- char c='#';
- switch(y_sign){
- case -1:
- c = 'd';
- break;
- case 0:
- c = 'h';
- break;
- case 1:
- c = 'u';
- break;
+ char c='#';
+ switch (y_sign)
+ {
+ case DOWN:
+ c = 'd';
+ break;
+ case CENTER:
+ c = 'h';
+ break;
+ case UP:
+ c = 'u';
+ break;
default:
- assert(false);
+ assert (false);
}
- return c;
+ return c;
}
-Symbol
-Lookup::half_slur_middlepart(Real &dx, int dir) const
+Atom
+Lookup::half_slur_middlepart (Real &dx, Direction dir) const
{
- if (dx >= 400 PT) {// todo
- WARN<<"halfslur too large" <<print_dimen(dx)<< "shrinking (ugh)\n";
- dx = 400 PT;
+ // todo
+ if (dx >= 400 PT)
+ {
+ WARN<<_("halfslur too large") <<print_dimen (dx)<< _("shrinking (ugh)\n");
+ dx = 400 PT;
}
- int widx = int(floor(dx / 4.0));
- dx = widx * 4.0;
- if (widx) widx --;
- else {
- WARN << "slur too narrow\n";
+ int widx = int (floor (dx / 4.0));
+ dx = widx * 4.0;
+ if (widx) widx --;
+ else
+ {
+ WARN << _("slur too narrow\n");
}
- Symbol s;
-
- s.dim.y() = Interval(min(0,0), max(0,0)); // todo
- s.dim.x() = Interval(0,dx);
+ Atom s;
- String f = String("\\hslurchar");
- f += direction_char(0);
+ s.dim_[Y_AXIS] = Interval (min (0, 0), max (0, 0)); // todo
+ s.dim_[X_AXIS] = Interval (-dx/2, dx/2);
- int idx = widx;
- if (dir < 0)
- idx += 128;
+ String f = String ("\\hslurchar");
+ f += direction_char (CENTER);
+
+ int idx = widx;
+ if (dir < 0)
+ idx += 128;
- assert (idx < 256);
+ assert (idx < 256);
- f+=String( "{" ) + String( idx ) + "}";
- s.tex = f;
- Atom a(s);
- a.translate(dx/2, X_AXIS);
- s.tex = a.TeX_string();
+ f +=String ("{") + String (idx) + "}";
+ s.tex_ = f;
+ s.translate_axis (dx/2, X_AXIS);
- return s;
+ return s;
}
-Symbol
-Lookup::half_slur(int dy, Real &dx, int dir, int xpart) const
+
+/*
+ The halfslurs have their center at the end pointing away from the notehead.
+ This lookup translates so that width() == [0, w]
+ */
+
+Atom
+Lookup::half_slur (int dy, Real &dx, Direction dir, int xpart) const
{
- Real orig_dx = dx;
- if (!xpart)
- return half_slur_middlepart(dx, dir);
-
- int widx;
-
- if (dx >= 96 PT) {
- WARN << "Slur half too wide." << print_dimen(orig_dx) << " shrinking (ugh)\n";
- dx = 96 PT;
+ Real orig_dx = dx;
+ if (!xpart)
+ return half_slur_middlepart (dx, dir);
+
+ int widx;
+
+ if (dx >= 96 PT)
+ {
+ WARN << _("Slur half too wide.") << print_dimen (orig_dx) << _(" shrinking (ugh)\n");
+ dx = 96 PT;
}
- widx = int(rint(dx/12.0));
- dx = widx*12.0;
- if (widx)
- widx --;
- else {
- WARN << "slur too narrow " << print_dimen(orig_dx)<<"\n";
+ widx = int (rint (dx/12.0));
+ dx = widx*12.0;
+ if (widx)
+ widx --;
+ else
+ {
+ WARN << _("slur too narrow ") << print_dimen (orig_dx)<<"\n";
}
-
- Symbol s;
- s.dim.x() = Interval(0,dx);
- s.dim.y() = Interval(min(0,dy), max(0,dy));
+ Atom s;
+ s.dim_[X_AXIS] = Interval (0, dx);
+ s.dim_[Y_AXIS] = Interval (min (0, dy), max (0, dy));
- String f = String("\\hslurchar");
- f+= direction_char(dir);
+ String f = String ("\\hslurchar");
- int hidx = dy;
- if (hidx <0)
- hidx = -hidx;
- hidx --;
- int idx =-1;
+ f+= direction_char (dir);
- idx = widx * 16 + hidx;
- if (xpart < 0)
- idx += 128;
-
- assert (idx < 256);
- f+=String( "{" ) + String( idx ) + "}";
-
-
- s.tex = f;
-
- return s;
+ int hidx = dy;
+ if (hidx <0)
+ hidx = -hidx;
+ hidx --;
+ int idx =-1;
+
+ idx = widx * 16 + hidx;
+ if (xpart < 0)
+ idx += 128;
+
+ assert (idx < 256);
+ f+=String ("{") + String (idx) + "}";
+
+ s.tex_ = f;
+
+ return s;
}
-Symbol
-Lookup::slur (int dy , Real &dx, int dir) const
+Atom
+Lookup::ps_slur (Real dy , Real dx, Real ht, Real dir) const
{
- assert(dx >=0 && abs(dir) <= 1);
- int y_sign = sign(dy);
-
- bool large = abs(dy) > 8;
-
- if (y_sign) {
- large |= dx>= 4*16 PT;
- } else
- large |= dx>= 4*54 PT;
-
- if (large) {
- return big_slur(dy, dx, dir);
+ String ps = "\\embeddedps{\n";
+
+ ps += String_convert::double_str (dx) + " "
+ + String_convert::double_str (dy) + " "
+ + String_convert::double_str (ht) + " "
+ + String_convert::double_str (dir) +
+ " draw_slur}";
+
+ /*
+ slurs are rarely wider than 100pt:
+ precision of 3 yields maximum (slur spanning page)
+ error of: 1%% * 6*72pt === 0.4pt = 0.14 mm
+ */
+ String dx_str = String_convert::precision_str (dx, 4);
+ String dy_str = String_convert::precision_str (dy, 3);
+ String dir_str = String_convert::int_str ((int)dir);
+ String name = "feta-sleur-" + dx_str + "-" + dy_str + "-" + dir_str;
+ int i = name.index_i ('.');
+ while (i != -1)
+ {
+ *(name.ch_l () + i) = 'x';
+ i = name.index_i ('.');
}
- Real orig_dx = dx;
- int widx = int(floor(dx/4.0)); // slurs better too small..
- dx = 4.0 * widx;
- if (widx)
- widx --;
- else {
- WARN << "slur too narrow: " << print_dimen(orig_dx) << "\n";
+
+ String mf = "\\embeddedmf{" + name + "}{\n";
+ mf += "mode_setup;\n";
+ mf += "staffsize\\#:="
+ + String_convert::int_str ((int)paper_l_->get_var ("barsize"), "%d")
+ + "pt\\#;\n";
+ mf += "interline#:=staffsize#/4;\n";
+ mf += "stafflinethickness#:=0.1interline#;\n";
+ mf += "input feta-sleur;\n";
+ mf += "slurchar(" + dx_str + "," + dy_str + "," + dir_str + ");\n";
+ mf += "end.\n";
+ mf += "}\n";
+
+ Atom s;
+ s.tex_ = ps + mf;
+ return s;
+}
+
+Atom
+Lookup::tex_slur (int dy , Real &dx, Direction dir) const
+{
+ assert (abs ((int)dir) <= 1);
+ Atom s;
+ Direction y_sign = (Direction) sign (dy);
+
+ bool large = abs (dy) > 8;
+
+ if (y_sign)
+ {
+ large |= dx>= 4*16 PT;
}
+ else
+ large |= dx>= 4*54 PT;
- int hidx = dy;
- if (hidx <0)
- hidx = -hidx;
- hidx --;
- if (hidx > 8) {
- WARN<<"slur to steep: " << dy << " shrinking (ugh)\n";
+ if (large)
+ {
+ s = big_slur (dy, dx, dir);
+ return s;
+ }
+ Real orig_dx = dx;
+ int widx = int (floor (dx/4.0)); // slurs better too small..
+ dx = 4.0 * widx;
+ if (widx)
+ widx --;
+ else
+ {
+ WARN << _("slur too narrow: ") << print_dimen (orig_dx) << "\n";
}
-
- Symbol s;
- s.dim.x() = Interval(0,dx);
- s.dim.y() = Interval(min(0,dy), max(0,dy));
-
- String f = String("\\slurchar") + String( direction_char(y_sign) );
-
- int idx=-1;
- if (y_sign) {
- idx = hidx * 16 + widx;
- if (dir < 0)
- idx += 128;
- } else {
- if (dx >= 4*54 PT) {
- WARN << "slur too wide: " << print_dimen(dx) <<
- " shrinking (ugh)\n";
- dx = 4*54 PT;
+
+ int hidx = dy;
+ if (hidx <0)
+ hidx = -hidx;
+ hidx --;
+ if (hidx > 8)
+ {
+ WARN<<_("slur to steep: ") << dy << _(" shrinking (ugh)\n");
+ }
+
+ String f = String ("\\slurchar") + String (direction_char (y_sign));
+
+ int idx=-1;
+ if (y_sign)
+ {
+ idx = hidx * 16 + widx;
+ if (dir < 0)
+ idx += 128;
+ }
+ else
+ {
+ if (dx >= 4*54 PT)
+ {
+ WARN << _("slur too wide: ") << print_dimen (dx) <<
+ _(" shrinking (ugh)\n");
+ dx = 4*54 PT;
}
- idx = widx;
- if (dir < 0)
- idx += 54;
+ idx = widx;
+ if (dir < 0)
+ idx += 54;
}
-
- assert (idx < 256);
- f+=String( "{" ) + String( idx ) + "}";
- s.tex = f;
-
- Atom a(s);
- a.translate(dx/2, X_AXIS);
- s.dim = a.extent();
- s.tex = a.TeX_string();
- return s;
+
+ assert (idx < 256);
+ f+=String ("{") + String (idx) + "}";
+ s.tex_ = f;
+ s.translate_axis (dx/2, X_AXIS);
+ return s;
}
-Symbol
-Lookup::big_slur(int dy , Real &dx, int dir) const
+Atom
+Lookup::big_slur (int dy , Real &dx, Direction dir) const
{
- assert(dx >= 24 PT);
- Real slur_extra =abs(dy) /2.0 + 2;
- int l_dy = int(Real (dy)/2 + slur_extra*dir);
- int r_dy = dy - l_dy;
-
- Real internote_f = paper_l_->internote_f();
- Real left_wid = dx/4.0;
- Real right_wid = left_wid;
-
- Atom l = half_slur(l_dy, left_wid, dir, -1);
- Atom r = half_slur(r_dy, right_wid, dir, 1);
- Real mid_wid = dx - left_wid - right_wid;
-
- Atom m = half_slur(0, mid_wid, dir, 0);
-
- Molecule mol;
- mol.add(l);
- Atom a(m);
- a.translate(slur_extra * internote_f, Y_AXIS);
- mol.add_right(m);
- mol.add_right(r);
- mol.translate( l_dy * internote_f, Y_AXIS);
- Symbol s;
- s.tex = mol.TeX_string();
- s.dim = mol.extent();
- return s;
+ if (dx < 24 PT)
+ {
+ warning (_("big_slur too small ") + print_dimen (dx) + _(" (stretching)"));
+ dx = 24 PT;
+ }
+
+ Real slur_extra =abs (dy) /2.0 + 2;
+ int l_dy = int (Real (dy)/2 + slur_extra*dir);
+ int r_dy = dy - l_dy;
+
+ Real internote_f = paper_l_->internote_f();
+ Real left_wid = dx/4.0;
+ Real right_wid = left_wid;
+
+ Atom l = half_slur (l_dy, left_wid, dir, -1);
+
+
+ Atom r = half_slur (r_dy, right_wid, dir, 1);
+ Real mid_wid = dx - left_wid - right_wid;
+
+ Molecule mol;
+ mol.add (l);
+ Atom a (half_slur (0, mid_wid, dir, 0));
+ mol.add_at_edge (X_AXIS, RIGHT, a);
+ mol.add_at_edge (X_AXIS, RIGHT, r);
+
+ mol.translate_axis (l_dy * internote_f, Y_AXIS);
+ Atom s;
+ s.tex_ = mol.TeX_string();
+ s.dim_ = mol.extent();
+ return s;
}
+Atom
+Lookup::slur (Real &dy_f , Real &dx, Real ht, Direction dir) const
+{
+ if (dx < 0)
+ {
+ warning (_("Negative slur/tie length: ") + print_dimen (dx));
+ dx = 4.0 PT;
+ }
+ Atom s;
+
+ if (postscript_global_b)
+ s = ps_slur (dy_f, dx, ht, dir);
+ else
+ {
+ Real nh = paper_l_->internote_f ();
+ int dy_i = (int) rint(dy_f / nh);
+
+ s = tex_slur (dy_i, dx, dir);
+ dy_f = dy_i * nh;
+ }
+
+ s.dim_[X_AXIS] = Interval (0, dx);
+ s.dim_[Y_AXIS] = Interval (0 <? dy_f, 0 >? dy_f);
+ return s;
+}