+2005-09-04 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * input/regression/tie-chord.ly (testLong): add a chord in 4ths
+
+ * lily/tie.cc (get_configuration): update bezier shape as we
+ change Y positions.
+ (get_configuration): don't move large ties if we're outside of the
+ staff.
+
+2005-09-01 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * scm/define-markup-commands.scm (strut): swap X and Y dims.
+
2005-09-03 Jan Nieuwenhuizen <janneke@gnu.org>
* .cvsignore: Add auto-generated configure files and then some.
* lily/tie-column.cc (new_directions): put Tie down on center
staff line.
- * lily/script-interface.cc (before_line_breaking): use Grob::programming_error
+ * lily/script-interface.cc (before_line_breaking): use
+ Grob::programming_error
* scm/ps-to-png.scm (make-ps-images): use pngalpha device.
Real arg () const;
Real length () const;
-
+ bool is_sane () const;
Offset operator *= (Offset z2)
{
*this = complex_multiply (*this, z2);
{
return sqrt (sqr (coordinate_a_[X_AXIS]) + sqr (coordinate_a_[Y_AXIS]));
}
+
+bool
+Offset::is_sane () const
+{
+ return !isnan (coordinate_a_[X_AXIS])
+ && !isnan (coordinate_a_ [Y_AXIS])
+ && !isinf (coordinate_a_[X_AXIS])
+ && !isnan (coordinate_a_[Y_AXIS]);
+}
<a' c d f> ~ <a c d f>
<a c e f> ~ <a c e f>
- <a b c d e> ~ <a b c d e>
+ <f b e a>4 ~ <f b e a>
}
}
\relative c' {
<c e f a>2 ~ <c e f a>8
<c e g a>2 ~ <c e g a>8
- <a' c d f>2 ~ <a c d f>8
- <a c e f>2 ~ <a c e f>8
+ <a' c d f>2 ~ <a c d f>8
+ <a c e f>2 ~ <a c e f>8
+ <f b e a>2 ~ <f b e a>8
}
}
static Direction get_direction (Grob *);
static void set_stemend (Grob *, Real);
static Direction get_default_dir (Grob *);
- static Slice Stem::beam_multiplicity (Grob *);
+ static Slice beam_multiplicity (Grob *);
static Real thickness (Grob *);
static int head_count (Grob *);
static bool is_invisible (Grob *);
static int compare (Grob *const &s1,
Grob *const &s2);
+ static
+ Interval get_default_attachments (Spanner *me, Grob *common, Real gap,
+ int *staff_position, bool *in_between);
};
(c) 2000--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
+#include "tie-column.hh"
+
#include <math.h>
#include <map>
#include <set>
+
+#include "stencil.hh"
#include "stem.hh"
#include "skyline.hh"
#include "staff-symbol-referencer.hh"
#include "warn.hh"
-#include "tie-column.hh"
#include "paper-column.hh"
#include "spanner.hh"
#include "pointer-group-interface.hh"
for (int i = 0; i < boxes.size (); i++)
insert_extent_into_skyline (&skyline_drul->elem_ref (d),
boxes[i], Y_AXIS, -d);
+ if (stem
+ && !Stem::is_invisible (stem))
+ {
+ Interval x;
+ x.add_point (stem->relative_coordinate (common, X_AXIS));
+ x.widen (staff_space / 20); // ugh.
+ Interval y;
+ y.add_point (Stem::stem_end_position (stem) * staff_space * .5);
+
+ Direction stemdir = Stem::get_direction (stem);
+ y.add_point (Stem::head_positions (stem)[-stemdir]
+ * staff_space * .5);
+
+ insert_extent_into_skyline (&skyline_drul->elem_ref (d),
+ Box (x,y), Y_AXIS, -d);
+
+
+
+ if (d == LEFT)
+ {
+ Box flag_box = Stem::get_translated_flag (stem).extent_box ();
+ flag_box.translate( Offset (x[RIGHT], X_AXIS));
+ insert_extent_into_skyline (&skyline_drul->elem_ref (d),
+ flag_box,
+ Y_AXIS, -d);
+ }
+ }
+
+
+
Direction updowndir = DOWN;
do
x[-d] = b[X_AXIS].linear_combination (-d / 2);
}
- if (stem
- && !Stem::is_invisible (stem)
- && updowndir == get_grob_direction (stem))
- x.unite (robust_relative_extent (stem, common, X_AXIS));
-
if (!x.is_empty ())
(*skyline_drul)[d].boundary (updowndir, 0).height_ = x[-d];
}
conf.attachment_x_.intersect (get_skyline_attachment (skylines,
y + conf.dir_ * staff_space * .5));
+
conf.delta_y_ += line_dy;
conf.attachment_x_.widen (-gap);
if (!on_line
for (int i = 0; i < tie_configs.size (); i++)
{
Tie_configuration * conf = &tie_configs.elem_ref (i);
- if (Staff_symbol_referencer::on_staffline (ties[0], int (rint (conf->position_)))
- && conf->height (details) < 0.4 * staff_space
- && (positions_taken.find (int (rint (conf->position_ + conf->dir_)))
- == positions_taken.end ()))
- {
- positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
- conf->delta_y_ += 0.2 * staff_space * conf->dir_;
- }
+
+ /*
+ on staff line and small enough, translate a little further
+ */
+ Real h = conf->height (details);
+ bool next_free = positions_taken.find (int (rint (conf->position_ + conf->dir_)))
+ == positions_taken.end ();
+ bool on_line = Staff_symbol_referencer::on_staffline (ties[0],
+ int (rint (conf->position_ + conf->delta_y_)));
+ if (next_free)
+ if (on_line && h < 0.4 * staff_space)
+ {
+ positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
+ conf->delta_y_ += 0.2 * staff_space * conf->dir_;
+ }
+ else if (!on_line && h > 0.6 * staff_space)
+ {
+ positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
+ conf->delta_y_ += 0.5 * staff_space * conf->dir_;
+ }
}
}
*/
+#include <math.h>
+
#include "tie.hh"
#include "bezier.hh"
#include "grob.hh"
#include "staff-symbol-referencer.hh"
-
+#include "warn.hh"
int
Tie_configuration::compare (Tie_configuration const &a,
Bezier
Tie_configuration::get_bezier (Tie_details const &details) const
{
- return slur_shape (attachment_x_.length(),
+ Real l = attachment_x_.length();
+ if (isnan (l) || isnan (l))
+ {
+ programming_error ("Inf or NaN encountered");
+ l = 1.0;
+ }
+ return slur_shape (l,
details.height_limit_,
details.ratio_);
}
Real
Tie_configuration::height (Tie_details const &details) const
{
- return slur_shape (attachment_x_.length(),
+ Real l = attachment_x_.length();
+
+ return slur_shape (l,
details.height_limit_,
details.ratio_).curve_point (0.5)[Y_AXIS];
}
}
Interval
-get_default_attachments (Spanner *me, Grob *common, Real gap,
- int *staff_position,
- bool *in_between
- )
+Tie::get_default_attachments (Spanner *me, Grob *common, Real gap,
+ int *staff_position,
+ bool *in_between
+ )
{
Real staff_space = Staff_symbol_referencer::staff_space (me);
Direction dir = get_grob_direction (me);
return ;
}
+ /*
+ UGH. Don't mirror Tie_configuration.
+ */
Direction dir = CENTER;
int tie_position = (int) Tie::get_position (me);
{
staff_position += dir;
in_space = false;
+
+ if (skylines)
+ {
+ Real y = staff_space * 0.5 * staff_position;
+ attachments = get_skyline_attachment (*skylines, y);
+ attachments.widen (-gap);
+ Bezier b = slur_shape (attachments.length(),
+ details.height_limit_,
+ details.ratio_);
+ Offset middle = b.curve_point (0.5);
+ Offset edge = b.curve_point (0.0);
+ dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]);
+ fits_in_space =
+ (dy < 0.6 * staff_space);
+ }
}
}
-
/*
Avoid flag.
- */
+ */
Grob *left_stem = unsmob_grob (me->get_bound (LEFT)->get_object ("stem"));
if (left_stem)
{
in_space = true;
staff_position += dir;
}
+
+ /*
+ ugh: code dup.
+ */
+ if (skylines)
+ {
+ Real y = staff_space * 0.5 * staff_position;
+ attachments = get_skyline_attachment (*skylines, y);
+ attachments.widen (-gap);
+
+ Bezier b = slur_shape (attachments.length(),
+ details.height_limit_,
+ details.ratio_);
+ Offset middle = b.curve_point (0.5);
+ Offset edge = b.curve_point (0.0);
+ dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]);
+ fits_in_space =
+ (dy < 0.6 * staff_space);
+ }
}
*/
if (staff_position == tie_position
&& in_space
+ && Staff_symbol_referencer::staff_radius (me) > fabs (staff_position) / 2
&& dy > 0.3 * staff_space)
{
staff_position += 2 * dir;
staff_position += 2*dir;
+ conf->dir_ = dir;
+ conf->position_ = staff_position;
if (in_space)
{
- if (fabs (dy) < 0.45 * staff_space)
+ if ((fabs (staff_position - tie_position) <= 1
+ && fabs (dy) < 0.45 * staff_space)
+ || fabs (dy) < 0.6 * staff_space)
{
/*
vertically center in space.
*/
- conf->dir_ = dir;
+ conf->dir_ = dir;
+ conf->position_ = staff_position;
conf->attachment_x_ = attachments;
- conf->center_tie_vertically(details);
+ conf->center_tie_vertically (details);
}
else
{
Real rounding_dy = (where - middle[Y_AXIS]);
conf->delta_y_ = rounding_dy;
- if (dir * b.curve_point (0.0)[Y_AXIS] <
+ if (dir * (b.curve_point (0.0)[Y_AXIS]
+ + conf->position_ * staff_space * 0.5
+ + conf->delta_y_) <
dir * tie_position * 0.5 * staff_space)
- conf->delta_y_ += staff_space * dir;
+ {
+ if (Staff_symbol_referencer::staff_radius (me) > fabs (tie_position) / 2)
+ conf->position_ += 2 * dir;
+ else
+ conf->position_ += dir;
+ }
}
- conf->dir_ = dir;
- conf->position_ = staff_position;
if (skylines)
{
SCM controls = SCM_EOL;
for (int i = 4; i--;)
- controls = scm_cons (ly_offset2scm (b.control_[i]), controls);
-
+ {
+ if (!b.control_[i].is_sane ())
+ programming_error ("Insane offset");
+ controls = scm_cons (ly_offset2scm (b.control_[i]), controls);
+ }
me->set_property ("control-points", controls);
}
(used ,boolean? "If set, this spacing column is kept in the spacing problem")
(when ,ly:moment? "Global time step associated with this column
happen?")
- (word-space ,ly:dimension? "space to insert between lyrics or
-words in texts.")
+ (word-space ,ly:dimension? "space to insert between words in texts.")
(width ,ly:dimension? "The width of a grob measured in staff space.")
(x-gap ,ly:dimension? "The horizontal gap between note head and tie.")
(zigzag-length ,ly:dimension? "The length of the lines of a
"Create a box of the same height as the space in the current font."
(let ((m (Text_interface::interpret_markup layout props " ")))
(ly:make-stencil (ly:stencil-expr m)
+ '(1000 . -1000)
(ly:stencil-extent m X)
- '(1000 . -1000))))
+ )))
;; todo: fix negative space