From 145389636e81237d560aba4d04abcb89fa60cd9c Mon Sep 17 00:00:00 2001 From: Dan Eble Date: Sun, 2 Nov 2014 20:32:57 -0500 Subject: [PATCH] Issue 4204: Convert ly::time-signature::print from C++ to Scheme. The user may add a new time signature style by calling add-simple-time-signature-style and providing a procedure returning markup. --- input/regression/time-signature-mensural.ly | 8 +- lily/include/time-signature.hh | 41 ----- lily/slur-scoring.cc | 3 +- lily/time-signature-engraver.cc | 1 - lily/time-signature.cc | 164 -------------------- scm/define-grob-interfaces.scm | 18 +++ scm/lily.scm | 1 + scm/time-signature-settings.scm | 39 +++++ scm/time-signature.scm | 35 +++++ 9 files changed, 98 insertions(+), 212 deletions(-) delete mode 100644 lily/include/time-signature.hh delete mode 100644 lily/time-signature.cc create mode 100644 scm/time-signature.scm diff --git a/input/regression/time-signature-mensural.ly b/input/regression/time-signature-mensural.ly index 3f80eb2642..32081c902f 100644 --- a/input/regression/time-signature-mensural.ly +++ b/input/regression/time-signature-mensural.ly @@ -5,10 +5,10 @@ } % N.B. It's strange that these warnings are doubled. -#(ly:expect-warning "time signature symbol `mensural11' not found") -#(ly:expect-warning "time signature symbol `mensural11' not found") -#(ly:expect-warning "time signature symbol `neomensural11' not found") -#(ly:expect-warning "time signature symbol `neomensural11' not found") +#(ly:expect-warning "Cannot find glyph timesig.mensural11") +#(ly:expect-warning "Cannot find glyph timesig.mensural11") +#(ly:expect-warning "Cannot find glyph timesig.neomensural11") +#(ly:expect-warning "Cannot find glyph timesig.neomensural11") \layout { indent = 0 } diff --git a/lily/include/time-signature.hh b/lily/include/time-signature.hh deleted file mode 100644 index 784af867b6..0000000000 --- a/lily/include/time-signature.hh +++ /dev/null @@ -1,41 +0,0 @@ -/* - This file is part of LilyPond, the GNU music typesetter. - - Copyright (C) 1996--2014 Han-Wen Nienhuys - - LilyPond is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - LilyPond is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with LilyPond. If not, see . -*/ - -#ifndef METER_HH -#define METER_HH - -#include "grob-interface.hh" -#include "lily-proto.hh" - -/** - Print a time_signature sign. - - TODO: - - 2+3+2/8 time_signatures -*/ -struct Time_signature -{ - DECLARE_GROB_INTERFACE (); - static Stencil special_time_signature (Grob *, SCM, int, int); - static Stencil numbered_time_signature (Grob *, int, int); - DECLARE_SCHEME_CALLBACK (print, (SCM)); -}; -#endif // METER_HH - diff --git a/lily/slur-scoring.cc b/lily/slur-scoring.cc index 7ffdacee0c..bb6b94a8c9 100644 --- a/lily/slur-scoring.cc +++ b/lily/slur-scoring.cc @@ -42,7 +42,6 @@ #include "staff-symbol-referencer.hh" #include "staff-symbol.hh" #include "stem.hh" -#include "time-signature.hh" #include "warn.hh" /* @@ -286,7 +285,7 @@ Slur_score_state::fill (Grob *me) && minmax (dir_, encompass_place, y_place) == encompass_place && (!extra_encompass_infos_[i].grob_->internal_has_interface (ly_symbol2scm ("key-signature-interface")) && !Clef::has_interface (extra_encompass_infos_[i].grob_) - && !Time_signature::has_interface (extra_encompass_infos_[i].grob_))) + && !extra_encompass_infos_[i].grob_->internal_has_interface (ly_symbol2scm ("time-signature-interface")))) { for (LEFT_and_RIGHT (d)) additional_ys[d] = minmax (dir_, diff --git a/lily/time-signature-engraver.cc b/lily/time-signature-engraver.cc index 587b9bffbc..aac2cc231b 100644 --- a/lily/time-signature-engraver.cc +++ b/lily/time-signature-engraver.cc @@ -24,7 +24,6 @@ #include "misc.hh" #include "moment.hh" #include "stream-event.hh" -#include "time-signature.hh" #include "warn.hh" #include "translator.icc" diff --git a/lily/time-signature.cc b/lily/time-signature.cc deleted file mode 100644 index c85b891932..0000000000 --- a/lily/time-signature.cc +++ /dev/null @@ -1,164 +0,0 @@ -/* - This file is part of LilyPond, the GNU music typesetter. - - Copyright (C) 1996--2014 Han-Wen Nienhuys - - LilyPond is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - LilyPond is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with LilyPond. If not, see . -*/ - -#include "time-signature.hh" - -#include "grob.hh" -#include "font-interface.hh" -#include "international.hh" -#include "output-def.hh" -#include "text-interface.hh" - -/* - TODO: - - this file should go ; The formatting can completely be done with - markups. -*/ - -MAKE_SCHEME_CALLBACK (Time_signature, print, 1); -SCM -Time_signature::print (SCM smob) -{ - Grob *me = Grob::unsmob (smob); - SCM st = me->get_property ("style"); - SCM frac = me->get_property ("fraction"); - int n = 4; - int d = 4; - if (scm_is_pair (frac)) - { - n = scm_to_int (scm_car (frac)); - d = scm_to_int (scm_cdr (frac)); - } - - Stencil m; - if (st == ly_symbol2scm ("single-digit")) - m = numbered_time_signature (me, n, 0); - else if (scm_is_symbol (st)) - m = special_time_signature (me, st, n, d); - else - m = numbered_time_signature (me, n, d); - - return m.smobbed_copy (); -} - -Stencil -Time_signature::special_time_signature (Grob *me, SCM scm_style, int n, int d) -{ - string style = robust_symbol2string (scm_style, "default"); - - if (style == "numbered") - return numbered_time_signature (me, n, d); - - if ((style == "default") || (style == "")) - style = ::to_string ("C"); - else if (style == "single-C") - { - if ((n != 2) && (n != 4)) - return numbered_time_signature (me, n, 0); - /* for any d, print 2/d as cut-C, 4/d as C */ - style = ::to_string ("C"); - d = n; - } - - if (style == "C") - { - if /* neither C2/2 nor C4/4 */ - (((n != 2) || (d != 2)) - && ((n != 4) || (d != 4))) - return numbered_time_signature (me, n, d); - } - - string char_name = style + ::to_string (n) + ::to_string (d); - me->set_property ("font-encoding", ly_symbol2scm ("fetaMusic")); - Stencil out = Font_interface::get_default_font (me) - ->find_by_name ("timesig." + char_name); - if (!out.is_empty ()) - return out; - - /* If there is no such symbol, we default to the numbered style. - (Here really with a warning!) */ - me->warning (_f ("time signature symbol `%s' not found; " - "reverting to numbered style", char_name)); - return numbered_time_signature (me, n, d); -} - -Stencil -Time_signature::numbered_time_signature (Grob *me, int num, int den) -{ - SCM chain = me->get_property_alist_chain (Font_interface::text_font_alist_chain (me)); - chain = scm_cons (scm_list_1 (scm_cons (ly_symbol2scm ("font-encoding"), - ly_symbol2scm ("fetaText"))), - chain); - - SCM sn = Text_interface::interpret_markup (me->layout ()->self_scm (), chain, - ly_string2scm (::to_string (num))); - SCM sd = Text_interface::interpret_markup (me->layout ()->self_scm (), chain, - ly_string2scm (::to_string (den))); - - Stencil n = *Stencil::unsmob (sn); - Stencil d = *Stencil::unsmob (sd); - - n.align_to (X_AXIS, CENTER); - d.align_to (X_AXIS, CENTER); - Stencil m; - if (den) - { - m.add_at_edge (Y_AXIS, UP, n, 0.0); - m.add_at_edge (Y_AXIS, DOWN, d, 0.0); - } - else - { - m = n; - m.align_to (Y_AXIS, CENTER); - } - - m.align_to (X_AXIS, LEFT); - - return m; -} - -ADD_INTERFACE (Time_signature, - "A time signature, in different styles. The following values" - " for @code{style} are are recognized:\n" - "\n" - "@table @code\n" - "@item C\n" - "4/4 and 2/2 are typeset as C and struck C, respectively." - " All other time signatures are written with two digits." - " The value @code{default} is equivalent to @code{C}.\n" - "@item neomensural\n" - "2/2, 3/2, 2/4, 3/4, 4/4, 6/4, 9/4, 4/8, 6/8, and 9/8 are" - " typeset with neo-mensural style mensuration marks. All" - " other time signatures are written with two digits.\n" - "@item mensural\n" - "2/2, 3/2, 2/4, 3/4, 4/4, 6/4, 9/4, 4/8, 6/8, and 9/8 are" - " typeset with mensural style mensuration marks. All other" - " time signatures are written with two digits.\n" - "@item single-digit\n" - "All time signatures are typeset with a single digit, e.g.," - " 3/2 is written as 3.\n" - "@item numbered\n" - "All time signatures are typeset with two digits.\n" - "@end table", - - /* properties */ - "fraction " - "style " - ); diff --git a/scm/define-grob-interfaces.scm b/scm/define-grob-interfaces.scm index 2321e1c903..0afa960a5f 100644 --- a/scm/define-grob-interfaces.scm +++ b/scm/define-grob-interfaces.scm @@ -317,6 +317,24 @@ interesting enough to maintain a hara-kiri staff." "A note head in tablature." '(details display-cautionary span-start)) +(ly:add-interface + 'time-signature-interface + "A time signature, in different styles. The following values for @code{style} are are recognized: + + @table @code + @item C + 4/4 and 2/2 are typeset as C and struck C, respectively. All other time signatures are written with two digits. The value @code{default} is equivalent to @code{C}. + @item neomensural + 2/2, 3/2, 2/4, 3/4, 4/4, 6/4, 9/4, 4/8, 6/8, and 9/8 are typeset with neo-mensural style mensuration marks. All other time signatures are written with two digits. + @item mensural + 2/2, 3/2, 2/4, 3/4, 4/4, 6/4, 9/4, 4/8, 6/8, and 9/8 are typeset with mensural style mensuration marks. All other time signatures are written with two digits. + @item single-digit + All time signatures are typeset with a single digit, e.g., 3/2 is written as 3. + @item numbered + All time signatures are typeset with two digits. + @end table" + '(fraction style)) + (ly:add-interface 'trill-spanner-interface "A trill spanner." diff --git a/scm/lily.scm b/scm/lily.scm index 3ba26bc6dc..7f3f2975ac 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -555,6 +555,7 @@ messages into errors.") "part-combiner.scm" "autochange.scm" "define-music-properties.scm" + "time-signature.scm" "time-signature-settings.scm" "auto-beam.scm" "chord-name.scm" diff --git a/scm/time-signature-settings.scm b/scm/time-signature-settings.scm index 9773f714a6..bee620eb9f 100644 --- a/scm/time-signature-settings.scm +++ b/scm/time-signature-settings.scm @@ -363,6 +363,45 @@ a fresh copy of the list-head is made." " (interpret-markup layout props (format-compound-time time-sig))) +(add-simple-time-signature-style 'numbered make-compound-meter-markup) + +(add-simple-time-signature-style 'single-digit + (lambda (fraction) (make-compound-meter-markup (car fraction)))) + +;;;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +;;; Formatting of symbolic time signatures + +(define-public (make-glyph-time-signature-markup style fraction) + "Make markup for a symbolic time signature. If the music font does not have a glyph for the requested style and fraction, issue a warning and make a numbered time signature instead." + (make-first-visible-markup + (list (make-musicglyph-markup (string-append + "timesig." + (symbol->string style) + (number->string (car fraction)) + (number->string (cdr fraction)))) + (make-compound-meter-markup fraction)))) + +(define-public (make-c-time-signature-markup fraction) + "Make markup for the `C' time signature style." + (let ((n (car fraction)) + (d (cdr fraction))) + ; check specific fractions to avoid warnings when no glyph exists + (if (or (and (= n 2) (= d 2)) + (and (= n 4) (= d 4))) + (make-glyph-time-signature-markup 'C fraction) + (make-compound-meter-markup fraction)))) + +(add-simple-time-signature-style 'C make-c-time-signature-markup) +(add-simple-time-signature-style 'default make-c-time-signature-markup) + +(define-public (make-single-c-time-signature-markup fraction) + "Make markup for the `single-C' time signature style." + (let ((n (car fraction))) + (if (or (= n 2) (= n 4)) ; numerator only + (make-glyph-time-signature-markup 'C (cons n n)) + (make-compound-meter-markup n)))) + +(add-simple-time-signature-style 'single-C make-single-c-time-signature-markup) ;;;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ;;; Measure length calculation of (possibly complex) compound time signatures diff --git a/scm/time-signature.scm b/scm/time-signature.scm new file mode 100644 index 0000000000..d4f678d168 --- /dev/null +++ b/scm/time-signature.scm @@ -0,0 +1,35 @@ +;;;; This file is part of LilyPond, the GNU music typesetter. +;;;; +;;;; Copyright (C) 2014 Daniel Eble +;;;; +;;;; LilyPond is free software: you can redistribute it and/or modify +;;;; it under the terms of the GNU General Public License as published by +;;;; the Free Software Foundation, either version 3 of the License, or +;;;; (at your option) any later version. +;;;; +;;;; LilyPond is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;;; GNU General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with LilyPond. If not, see . + +(define-public (ly:time-signature::print grob) + "Print routine for time signatures." + (let* ((fraction (ly:grob-property grob 'fraction '(4 . 4))) + (style (ly:grob-property grob 'style 'default)) + (proc (assoc-get style time-signature-style-markup-procedures)) + (markup (if (procedure? proc) + (proc fraction) + (make-glyph-time-signature-markup style fraction)))) + (grob-interpret-markup grob markup))) + +(define-public (add-simple-time-signature-style style proc) + "Specify the procedure @{proc} returning markup for a time signature +style @var{style}. The procedure is called with one argument, the +pair @code{(@var{numerator} . @var{denominator})}." + (set! time-signature-style-markup-procedures + (acons style proc time-signature-style-markup-procedures))) + +(define-session time-signature-style-markup-procedures `()) -- 2.39.2