summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHan-Wen Nienhuys <hanwen@xs4all.nl>2005-08-03 18:23:47 +0000
committerHan-Wen Nienhuys <hanwen@xs4all.nl>2005-08-03 18:23:47 +0000
commit3032301cc8609347d997cd4367aa7ab055196e80 (patch)
tree90fd95491879bd6da52bd3070e18b7fe17c5d5ec
parent1c233f4264a7ec737594fca7bb82a5eb88ec1026 (diff)
* input/regression/markup-arrows.ly: new file.
* lily/tuplet-bracket.cc: document new behavior. * input/regression/tuplet-broken.ly: new file. Demonstrate tuplets with line breaks. * scm/define-markup-commands.scm (arrow-head): arrow-head markup command. * scm/define-grobs.scm (all-grob-descriptions): set arrows as default * lily/tuplet-bracket.cc: add edge-text property. add break-overshoot. (print): read break-overshoot. (print): read edge-text, add stencils. * mf/feta-arrow.mf: new file. * mf/feta-generic.mf: add feta-arrow.
-rw-r--r--ChangeLog23
-rw-r--r--Documentation/topdocs/NEWS.tely27
-rw-r--r--flower/include/interval.hh5
-rw-r--r--input/regression/markup-arrows.ly25
-rw-r--r--input/regression/tuplet-broken.ly30
-rw-r--r--lily/book.cc2
-rw-r--r--lily/dynamic-text-spanner.cc4
-rw-r--r--lily/include/text-interface.hh2
-rw-r--r--lily/mark-engraver.cc4
-rw-r--r--lily/ottava-bracket.cc2
-rw-r--r--lily/paper-book.cc2
-rw-r--r--lily/parser.yy2
-rw-r--r--lily/part-combine-engraver.cc2
-rw-r--r--lily/text-interface.cc4
-rw-r--r--lily/text-spanner.cc2
-rw-r--r--lily/tuplet-bracket.cc85
-rw-r--r--mf/feta-arrow.mf139
-rw-r--r--mf/feta-generic.mf3
-rw-r--r--mf/feta-test-generic.mf6
-rw-r--r--scm/define-grob-properties.scm2
-rw-r--r--scm/define-grobs.scm3
-rw-r--r--scm/define-markup-commands.scm22
22 files changed, 366 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index ae71dcec5b..ea86c198a4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2005-08-03 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * input/regression/markup-arrows.ly: new file.
+
+ * lily/tuplet-bracket.cc: document new behavior.
+
+ * input/regression/tuplet-broken.ly: new file. Demonstrate tuplets
+ with line breaks.
+
+ * scm/define-markup-commands.scm (arrow-head): arrow-head markup command.
+
+ * scm/define-grobs.scm (all-grob-descriptions): set arrows as
+ default
+
+ * lily/tuplet-bracket.cc: add edge-text property.
+ add break-overshoot.
+ (print): read break-overshoot.
+ (print): read edge-text, add stencils.
+
+ * mf/feta-arrow.mf: new file.
+
+ * mf/feta-generic.mf: add feta-arrow.
+
2005-08-03 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/lilypond-book.itely (An example of a
diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely
index fa47c14a57..42ec9c6735 100644
--- a/Documentation/topdocs/NEWS.tely
+++ b/Documentation/topdocs/NEWS.tely
@@ -34,6 +34,33 @@ See user manual, \NAME\
@itemize @bullet
@item
+Tuplet brackets get arrows when they are broken across a line.
+
+@lilypond[fragment,raggedright,verbatim,relative=2]
+\times 4/5 {
+ c c c \bar "empty" \break c c
+}
+@end lilypond
+
+This feature was sponsored by Trevor Baca.
+
+
+@item
+Arrow heads were added to the Feta font.
+
+@lilypond[]
+\lyrics {
+ \markup {
+ filled, to the right: \hspace #2.0 \fontsize #6 \arrow-head #0 #1 ##t
+ open, down: \hspace #2.0 \fontsize #6 \arrow-head #1 #-1 ##f
+ }
+}
+@end lilypond
+
+These glyphs have been sponsored by Trevor Baca.
+
+
+@item
Nested tuplets are automatically positioned,
@lilypond[fragment,raggedright,verbatim,relative=2]
diff --git a/flower/include/interval.hh b/flower/include/interval.hh
index c3471a5765..a6a92f204d 100644
--- a/flower/include/interval.hh
+++ b/flower/include/interval.hh
@@ -70,6 +70,11 @@ struct Interval_t : public Drul_array<T>
{
set_empty ();
}
+ Interval_t (Drul_array<T> const &src)
+ : Drul_array<T> (src)
+ {
+ }
+
Interval_t (T m, T M) : Drul_array<T> (m, M)
{
}
diff --git a/input/regression/markup-arrows.ly b/input/regression/markup-arrows.ly
new file mode 100644
index 0000000000..51a4c37004
--- /dev/null
+++ b/input/regression/markup-arrows.ly
@@ -0,0 +1,25 @@
+
+\header {
+ texidoc = "The feta font has arrow heads"
+}
+
+
+\lyrics {
+ \markup {
+
+ filled
+
+ \arrow-head #0 #1 ##t
+ \arrow-head #0 #-1 ##t
+ \arrow-head #1 #1 ##t
+ \arrow-head #1 #-1 ##t
+
+
+ \arrow-head #0 #1 ##f
+ \arrow-head #0 #-1 ##f
+ \arrow-head #1 #1 ##f
+ \arrow-head #1 #-1 ##f
+ }
+}
+
+\version "2.7.4"
diff --git a/input/regression/tuplet-broken.ly b/input/regression/tuplet-broken.ly
new file mode 100644
index 0000000000..43f7ca4e15
--- /dev/null
+++ b/input/regression/tuplet-broken.ly
@@ -0,0 +1,30 @@
+
+\header
+{
+ texidoc = "Broken tuplets are adorned with little arrows."
+}
+\version "2.7.4"
+
+\paper {
+ raggedright = ##t
+ indent = 0.0
+}
+
+
+\relative c'' {
+ \set tupletNumberFormatFunction = #fraction-tuplet-formatter
+
+ \override TupletBracket #'edge-text = #(cons
+ (markup #:fontsize 6
+ #:arrow-head 0 -1 #f)
+ (markup #:arrow-head 0 1 #f))
+ \times 11/19 {
+ c4 c4 c4 c4
+ \bar "empty" \break
+ c4 c4 c4 c4
+ c4 c4 c4 c4
+ \bar "empty" \break
+ c4 c4 c4 c4
+ c4 c4 c4
+ }
+}
diff --git a/lily/book.cc b/lily/book.cc
index a6279b531c..82d919f0e2 100644
--- a/lily/book.cc
+++ b/lily/book.cc
@@ -127,7 +127,7 @@ Book::process (Output_def *default_paper,
outputs = scm_cdr (outputs);
}
}
- else if (Text_interface::markup_p (scm_car (s)))
+ else if (Text_interface::is_markup (scm_car (s)))
paper_book->add_score (scm_car (s));
else
assert (0);
diff --git a/lily/dynamic-text-spanner.cc b/lily/dynamic-text-spanner.cc
index 5ed1f00cae..37b701cf65 100644
--- a/lily/dynamic-text-spanner.cc
+++ b/lily/dynamic-text-spanner.cc
@@ -101,8 +101,8 @@ Dynamic_text_spanner::print (SCM smob)
SCM text = index_get_cell (edge_text, d);
- if (Text_interface::markup_p (text))
- edge[d] = *unsmob_stencil (Text_interface::interpret_markup (layout->self_scm (), properties, text));
+ if (Text_interface::is_markup (text))
+ edge[d] = *unsmob_stencil (Text_interface::interpret_markup (layout->self_scm (), properties, text));
if (!edge[d].is_empty ())
edge[d].align_to (Y_AXIS, CENTER);
diff --git a/lily/include/text-interface.hh b/lily/include/text-interface.hh
index ce7d61d66d..6621a4dbb2 100644
--- a/lily/include/text-interface.hh
+++ b/lily/include/text-interface.hh
@@ -19,7 +19,7 @@ public:
DECLARE_SCHEME_CALLBACK (interpret_markup, (SCM, SCM, SCM));
DECLARE_SCHEME_CALLBACK (interpret_string, (SCM, SCM, SCM));
static bool has_interface (Grob *);
- static bool markup_p (SCM);
+ static bool is_markup (SCM);
};
#endif /* TEXT_ITEM */
diff --git a/lily/mark-engraver.cc b/lily/mark-engraver.cc
index 97b2649f50..26e9d5fbf0 100644
--- a/lily/mark-engraver.cc
+++ b/lily/mark-engraver.cc
@@ -101,7 +101,7 @@ Mark_engraver::process_music ()
SCM m = mark_ev_->get_property ("label");
SCM proc = get_property ("markFormatter");
- if (!Text_interface::markup_p (m)
+ if (!Text_interface::is_markup (m)
&& ly_is_procedure (proc))
{
if (!scm_is_number (m))
@@ -123,7 +123,7 @@ Mark_engraver::process_music ()
warning (_ ("rehearsalMark must have integer value"));
}
- if (Text_interface::markup_p (m))
+ if (Text_interface::is_markup (m))
text_->set_property ("text", m);
else
warning (_ ("mark label must be a markup object"));
diff --git a/lily/ottava-bracket.cc b/lily/ottava-bracket.cc
index 72f05cf592..80b98d2500 100644
--- a/lily/ottava-bracket.cc
+++ b/lily/ottava-bracket.cc
@@ -69,7 +69,7 @@ Ottava_bracket::print (SCM smob)
SCM properties = Font_interface::text_font_alist_chain (me);
SCM markup = me->get_property ("text");
Stencil text;
- if (Text_interface::markup_p (markup))
+ if (Text_interface::is_markup (markup))
text = *unsmob_stencil (Text_interface::interpret_markup (layout->self_scm (), properties, markup));
Drul_array<Real> shorten = robust_scm2interval (me->get_property ("shorten-pair"),
diff --git a/lily/paper-book.cc b/lily/paper-book.cc
index 79b4597464..dc373ea117 100644
--- a/lily/paper-book.cc
+++ b/lily/paper-book.cc
@@ -307,7 +307,7 @@ Paper_book::systems ()
system_list = scm_reverse (system_list);
systems_ = scm_append (scm_list_2 (system_list, systems_));
}
- else if (Text_interface::markup_p (scm_car (s)))
+ else if (Text_interface::is_markup (scm_car (s)))
{
SCM t = Text_interface::interpret_markup (paper_->self_scm (),
page_properties,
diff --git a/lily/parser.yy b/lily/parser.yy
index eb0dc92973..85b2fb1cb7 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -2698,7 +2698,7 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
*destination = p->self_scm ();
return OUTPUT_DEF_IDENTIFIER;
- } else if (Text_interface::markup_p (sid)) {
+ } else if (Text_interface::is_markup (sid)) {
*destination = sid;
if (is_lyric_state ())
return LYRIC_MARKUP_IDENTIFIER;
diff --git a/lily/part-combine-engraver.cc b/lily/part-combine-engraver.cc
index 44e9a81a65..eac99592e3 100644
--- a/lily/part-combine-engraver.cc
+++ b/lily/part-combine-engraver.cc
@@ -59,7 +59,7 @@ Part_combine_engraver::process_music ()
else if (what == ly_symbol2scm ("unisono"))
text = get_property ("aDueText");
- if (Text_interface::markup_p (text))
+ if (Text_interface::is_markup (text))
{
text_ = make_item ("CombineTextScript", event_->self_scm ());
text_->set_property ("text", text);
diff --git a/lily/text-interface.cc b/lily/text-interface.cc
index cb3484fb79..1c5cee670f 100644
--- a/lily/text-interface.cc
+++ b/lily/text-interface.cc
@@ -49,7 +49,7 @@ Text_interface::interpret_markup (SCM layout_smob, SCM props, SCM markup)
{
SCM func = scm_car (markup);
SCM args = scm_cdr (markup);
- if (!markup_p (markup))
+ if (!is_markup (markup))
programming_error ("markup head has no markup signature");
return scm_apply_2 (func, layout_smob, props, args);
@@ -81,7 +81,7 @@ Text_interface::print (SCM grob)
/* Ugh. Duplicated from Scheme. */
bool
-Text_interface::markup_p (SCM x)
+Text_interface::is_markup (SCM x)
{
return (scm_is_string (x)
|| (scm_is_pair (x)
diff --git a/lily/text-spanner.cc b/lily/text-spanner.cc
index 207c9f2087..52cd57f8d8 100644
--- a/lily/text-spanner.cc
+++ b/lily/text-spanner.cc
@@ -92,7 +92,7 @@ Text_spanner::print (SCM smob)
SCM text = index_get_cell (edge_text, d);
- if (Text_interface::markup_p (text))
+ if (Text_interface::is_markup (text))
edge[d] = *unsmob_stencil (Text_interface::interpret_markup (layout->self_scm (), properties, text));
if (!edge[d].is_empty ())
diff --git a/lily/tuplet-bracket.cc b/lily/tuplet-bracket.cc
index 5b80bb3c70..a13a896c49 100644
--- a/lily/tuplet-bracket.cc
+++ b/lily/tuplet-bracket.cc
@@ -46,14 +46,18 @@
#include "staff-symbol-referencer.hh"
#include "lookup.hh"
-static Grob *
-get_x_bound_grob (Grob *g, Direction my_dir)
+static Item *
+get_x_bound_item (Grob *me_grob, Direction hdir, Direction my_dir)
{
- if (Note_column::get_stem (g)
+ Spanner *me = dynamic_cast<Spanner*> (me_grob);
+ Item *g = me->get_bound (hdir);
+ if (Note_column::has_interface (g)
+ && Note_column::get_stem (g)
&& Note_column::dir (g) == my_dir)
{
g = Note_column::get_stem (g);
}
+
return g;
}
@@ -162,13 +166,27 @@ Tuplet_bracket::print (SCM smob)
Direction dir = get_grob_direction (me);
- Grob *lgr = get_x_bound_grob (columns[0], dir);
- Grob *rgr = get_x_bound_grob (columns.top (), dir);
+ Drul_array<Item *> bounds;
+ bounds[LEFT] = get_x_bound_item (me, LEFT, dir);
+ bounds[RIGHT] = get_x_bound_item (me, RIGHT, dir);
- Real x0 = robust_relative_extent (lgr, commonx, X_AXIS)[LEFT];
- Real x1 = robust_relative_extent (rgr, commonx, X_AXIS)[RIGHT];
- Real w = x1 -x0;
+ Interval x_span;
+ Direction d = LEFT;
+ do
+ {
+ x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS)[d];
+
+ if (bounds[d]->break_status_dir())
+ {
+ Interval overshoot (robust_scm2drul (me->get_property ("break-overshoot"),
+ Interval (0,0)));
+
+ x_span[d] += d * overshoot[d];
+ }
+ }
+ while (flip (&d) != LEFT);
+ Real w = x_span.length();
SCM number = me->get_property ("text");
Output_def *pap = me->get_layout ();
@@ -217,7 +235,20 @@ Tuplet_bracket::print (SCM smob)
scale_drul (&height, -ss * dir);
scale_drul (&flare, ss);
scale_drul (&shorten, ss);
+
+ do
+ {
+ if (bounds[d]->break_status_dir ())
+ {
+ height[d] = 0.0;
+ flare[d] = 0.0;
+ shorten[d] = 0.0;
+ }
+ }
+ while (flip (&d) != LEFT);
+
+
Stencil brack = make_bracket (me, Y_AXIS,
Offset (w, ry - ly),
height,
@@ -227,11 +258,35 @@ Tuplet_bracket::print (SCM smob)
*/
Interval (-0.5, 0.5) * gap + 0.1,
flare, shorten);
+
+ do
+ {
+ if (bounds[d]->break_status_dir ())
+ {
+ SCM properties = Font_interface::text_font_alist_chain (me);
+ SCM edge_text = me->get_property ("edge-text");
+
+ SCM text = index_get_cell (edge_text, d);
+ if (Text_interface::is_markup (text))
+ {
+ SCM t = Text_interface::interpret_markup (pap->self_scm (), properties,
+ text);
+
+ Stencil *edge_text = unsmob_stencil (t);
+ edge_text->translate_axis (x_span[d] - x_span[LEFT], X_AXIS);
+ mol.add_stencil (*edge_text);
+ }
+ }
+ }
+ while (flip (&d) != LEFT);
+
+
mol.add_stencil (brack);
}
mol.translate_axis (ly, Y_AXIS);
- mol.translate_axis (x0 - sp->get_bound (LEFT)->relative_coordinate (commonx, X_AXIS), X_AXIS);
+ mol.translate_axis (x_span[LEFT]
+ - sp->get_bound (LEFT)->relative_coordinate (commonx, X_AXIS), X_AXIS);
return mol.smobbed_copy ();
}
@@ -376,8 +431,8 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
if (!columns.size ())
return;
- Grob *lgr = get_x_bound_grob (columns[0], dir);
- Grob *rgr = get_x_bound_grob (columns.top (), dir);
+ Item *lgr = get_x_bound_item (me, LEFT, dir);
+ Item *rgr = get_x_bound_item (me, RIGHT, dir);
Real x0 = robust_relative_extent (lgr, commonx, X_AXIS)[LEFT];
Real x1 = robust_relative_extent (rgr, commonx, X_AXIS)[RIGHT];
@@ -608,10 +663,14 @@ Tuplet_bracket::add_tuplet_bracket (Grob *me, Grob *bracket)
ADD_INTERFACE (Tuplet_bracket,
"tuplet-bracket-interface",
- "A bracket with a number in the middle, used for tuplets.",
+ "A bracket with a number in the middle, used for tuplets. ",
+ "When the bracket spans a line break, the value of "
+ "@code{break-overshoot} determines how far it extends beyond the staff. "
+ "At a line break, the markups in the @code{edge-text} are printed "
+ "at the edges. "
"note-columns bracket-flare edge-height shorten-pair "
- "tuplets "
+ "tuplets edge-text break-overshoot "
"padding left-position right-position bracket-visibility "
"number-visibility thickness direction");
diff --git a/mf/feta-arrow.mf b/mf/feta-arrow.mf
new file mode 100644
index 0000000000..6a32af187e
--- /dev/null
+++ b/mf/feta-arrow.mf
@@ -0,0 +1,139 @@
+%
+% feta-arrow.mf -- draw arrow heads
+%
+% source file of the GNU LilyPond music typesetter
+%
+% (c) 2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
+%
+
+
+
+fet_begingroup ("arrowheads");
+
+
+%
+% Setup paths for upper half of arrow head pointing right.
+% CLOSE_PATH is for a closed arrow, OPEN_PATH is for the open arrow
+% OPEN_TENSION sets the tension for the part which forms the path in OPEN_PATH
+%
+def set_arrow_paths (expr width, height, open_tension, arrowlinethickness) =
+ save pat, finalpath,
+ tip_angle_o, tip_angle_c, tip_dir_c, tip_dir_o,
+ indent;
+ path pat, open_path, close_path;
+ pair tip_dir_o, tip_dir_c;
+
+ pickup pencircle scaled arrowlinethickness;
+
+ indent = linethickness/2;
+
+ lft x1 = -width;
+ rt x2 = 0;
+ top y1 = height;
+ y2 = 0;
+
+ z4 = z3;
+ y5 = 0;
+ x5 = x4 + indent;
+
+ pat := z1 .. tension open_tension .. z2{right};
+
+ penpos2 (arrowlinethickness, 90);
+ tip_dir_o := direction 0.0 of pat;
+ tip_angle_o := angle (tip_dir_o);
+ penpos1 (arrowlinethickness, 90 + tip_angle_o);
+ z3 = z1;
+ penpos3 (arrowlinethickness, tip_angle_o);
+
+ open_path := z1r{tip_dir_o} .. z2r{right}
+ .. z2l{left} .. z1l{-tip_dir_o} .. z3l .. cycle;
+
+ pat := z4 .. z5{down};
+ tip_dir_c := direction 0.0 of pat;
+ tip_angle_c := angle (tip_dir_c);
+ penpos4 (arrowlinethickness, 90+ tip_angle_c);
+ penpos5 (arrowlinethickness, 0);
+ z6 = z5;
+ penpos6 (arrowlinethickness, 90);
+
+ close_path := z4l{tip_dir_c} .. z5l{down} .. z6l{right}
+ .. z2l{right} .. z2r{left}
+ .. tension open_tension
+ .. z1r{-tip_dir_o}
+ .. z3l
+ .. cycle;
+
+enddef;
+
+fet_beginchar ("open", "open.01");
+ set_char_box (staff_space#, 0, 0.5 staff_space#, 0.5 staff_space#);
+ set_arrow_paths (staff_space, 0.5 staff_space, 1.0, 1.6 linethickness);
+ fill open_path;
+ addto currentpicture also currentpicture yscaled -1;
+ penlabels (1, 2, 3);
+ penlabels (4, 5, 6);
+fet_endchar;
+
+fet_beginchar ("open", "open.0M1");
+ set_char_box (0, staff_space#, 0.5 staff_space#, 0.5 staff_space#);
+ set_arrow_paths (staff_space, 0.5 staff_space, 1.0, 1.6 linethickness);
+ fill open_path;
+ addto currentpicture also currentpicture yscaled -1;
+ currentpicture := currentpicture xscaled -1;
+fet_endchar;
+
+fet_beginchar ("open", "open.11");
+ set_char_box (.5 staff_space#, .5 staff_space#,
+ 1.0 staff_space#, 0.0 staff_space#);
+ set_arrow_paths (staff_space, 0.5 staff_space, 1.0, 1.6 linethickness);
+ fill open_path;
+ addto currentpicture also currentpicture yscaled -1;
+ currentpicture := currentpicture rotated 90;
+fet_endchar;
+
+fet_beginchar ("open", "open.1M1");
+ set_char_box (.5 staff_space#, .5 staff_space#,
+ 0.0 staff_space#, 1.0 staff_space#);
+ set_arrow_paths (staff_space, 0.5 staff_space, 1.0, 1.6 linethickness);
+ fill open_path;
+ addto currentpicture also currentpicture yscaled -1;
+ currentpicture := currentpicture rotated 90;
+ currentpicture := currentpicture yscaled -1;
+fet_endchar;
+
+
+
+fet_beginchar ("close", "close.01");
+ set_char_box (staff_space#, 0, 0.5 staff_space#, 0.5 staff_space#);
+ set_arrow_paths (staff_space, 0.5 staff_space, 1.5, blot_diameter);
+ fill close_path;
+ addto currentpicture also currentpicture yscaled -1;
+fet_endchar;
+fet_beginchar ("close", "close.0M1");
+ set_char_box (0, staff_space#, 0.5 staff_space#, 0.5 staff_space#);
+ set_arrow_paths (staff_space, 0.5 staff_space, 1.5, blot_diameter);
+ fill close_path;
+ addto currentpicture also currentpicture yscaled -1;
+ currentpicture := currentpicture xscaled -1;
+fet_endchar;
+
+fet_beginchar ("close", "close.11");
+ set_char_box (.5 staff_space#, .5 staff_space# ,
+ 1.0 staff_space#, 0.0 staff_space#);
+ set_arrow_paths (staff_space, 0.5 staff_space, 1.5, blot_diameter);
+ fill close_path;
+ addto currentpicture also currentpicture yscaled -1;
+ currentpicture := currentpicture rotated 90;
+fet_endchar;
+
+fet_beginchar ("close", "close.1M1");
+ set_char_box (.5 staff_space#, .5 staff_space# ,
+ 0.0 staff_space#, 1.0 staff_space#);
+ set_arrow_paths (staff_space, 0.5 staff_space, 1.5, blot_diameter);
+ fill close_path;
+ addto currentpicture also currentpicture yscaled -1;
+ currentpicture := currentpicture rotated -90;
+fet_endchar;
+
+
+fet_endgroup ("arrowheads");
diff --git a/mf/feta-generic.mf b/mf/feta-generic.mf
index 1d75e0a5c0..dd508285aa 100644
--- a/mf/feta-generic.mf
+++ b/mf/feta-generic.mf
@@ -23,12 +23,15 @@ input feta-params;
font_x_height staff_space#;
+%% this is a fallback so we can run the font without including feta-bolletjes.
+black_notehead_width# := 1.0 staff_space#;
fet_beginfont("feta", design_size, "fetaMusic");
if test = 0:
input feta-eindelijk;
input feta-toevallig;
+ input feta-arrow;
input feta-puntje;
input feta-bolletjes;
input feta-schrift;
diff --git a/mf/feta-test-generic.mf b/mf/feta-test-generic.mf
index 9af341967b..44b0168dd2 100644
--- a/mf/feta-test-generic.mf
+++ b/mf/feta-test-generic.mf
@@ -6,12 +6,14 @@
%input feta-eindelijk;
%input feta-toevallig;
%input feta-puntje;
-input feta-bolletjes;
+%input feta-bolletjes;
+input feta-arrow;
+%input feta-schrift;
%input feta-schrift;
%input feta-banier;
% input feta-slag;
%input feta-klef;
-input feta-haak;
+%input feta-haak;
% input feta-haak;
%input feta-timesig;
%input feta-pendaal;
diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm
index 48441d58df..3e92408fad 100644
--- a/scm/define-grob-properties.scm
+++ b/scm/define-grob-properties.scm
@@ -112,6 +112,8 @@ For example, clefs are put after key signatures by setting
(break-glyph-function ,procedure? "This function determines the
appearance of a bar line at the line break. It takes a glyph and
break-direction and returns the glyph at a line break.")
+ (break-overshoot ,number-pair? "How much does a broken spanner
+stick out of its bounds?")
(breakable ,boolean? "Can this object appear at a line break,
like clefs and bar lines?")
(c0-position ,integer? "An integer indicating the position of
diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm
index da3cc4ff85..29e471b7ec 100644
--- a/scm/define-grobs.scm
+++ b/scm/define-grobs.scm
@@ -1484,7 +1484,10 @@
(padding . 1.1)
(thickness . 1.6)
(edge-height . (0.7 . 0.7))
+ (break-overshoot . (1.0 . 1.0))
(shorten-pair . (-0.2 . -0.2))
+ (edge-text . ,(cons (markup #:arrow-head 0 -1 #f)
+ (markup #:arrow-head 0 1 #f)))
(before-line-breaking-callback . ,Tuplet_bracket::before_line_breaking)
(after-line-breaking-callback . ,Tuplet_bracket::after_line_breaking)
(print-function . ,Tuplet_bracket::print)
diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm
index 2fe8b88336..fb045fce3e 100644
--- a/scm/define-markup-commands.scm
+++ b/scm/define-markup-commands.scm
@@ -810,11 +810,27 @@ recommend font for this is bold and italic"
(ly:stencil-extent stil X)
(ly:stencil-extent stil Y))))
-
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; glyphs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(def-markup-command (arrow-head layout props axis direction filled)
+ (integer? ly:dir? boolean?)
+ "produce an arrow head in specified direction and axis. Use the filled head if @var{filled} is specified."
+ (let*
+ ((name (format "arrowheads.~a.~a~a"
+ (if filled
+ "close"
+ "open")
+ axis
+ direction)))
+ (ly:font-get-glyph
+ (ly:paper-get-font layout (cons '((font-encoding . fetaMusic))
+ props))
+ name)))
+
(def-markup-command (musicglyph layout props glyph-name) (string?)
"This is converted to a musical symbol, e.g. @code{\\musicglyph
#\"accidentals.0\"} will select the natural sign from the music font.
@@ -869,6 +885,7 @@ letter 'A'."
(Text_interface::interpret_markup layout props
(number->markletter-string number->mark-alphabet-vector num)))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; the note command.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -957,6 +974,7 @@ a shortened down stem."
(let ((parsed (parse-simple-duration duration)))
(note-by-number-markup layout props (car parsed) (cadr parsed) dir)))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; translating.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1074,7 +1092,7 @@ that.
(interpret-markup layout props arg)
(* -0.5 (chain-assoc-get 'baseline-skip props))
Y))
-
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; brackets.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;