From 933ea175663dc544f1357dc087a653d8a4e4a7bd Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Tue, 12 Apr 2005 23:38:49 +0000 Subject: [PATCH] * ly/performer-init.ly: add CueVoice to MIDI too. * ps/music-drawing-routines.ps: new routine BeginEPSF / EndEPSF. * input/regression/markup-eps.ly: new file. * scm/framework-ps.scm (write-preamble): change order: vars should be inited before procedures. * scm/output-ps.scm (glyph-string): break lines. 255 chars is max for EPS files. * scm/define-markup-commands.scm (epsfile): add epsfile command. --- ChangeLog | 33 ++++++++++++++ GNUmakefile.in | 3 ++ configure.in | 2 + input/regression/markup-eps.ly | 17 +++++++ input/regression/{utf8.ly => utf-8.ly} | 0 lily/hairpin.cc | 34 ++++++++++++-- lily/include/hairpin.hh | 1 + lily/include/source-file.hh | 2 +- lily/source-file.cc | 62 ++++++++++++++++++++------ ly/performer-init.ly | 5 +++ ps/music-drawing-routines.ps | 23 ++++++++++ scm/define-grobs.scm | 1 + scm/define-markup-commands.scm | 55 +++++++++++++++++++++++ scm/framework-ps.scm | 12 +++-- scm/output-ps.scm | 4 +- 15 files changed, 230 insertions(+), 24 deletions(-) create mode 100644 input/regression/markup-eps.ly rename input/regression/{utf8.ly => utf-8.ly} (100%) diff --git a/ChangeLog b/ChangeLog index ddc9b87c03..0670538b67 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2005-04-13 Han-Wen Nienhuys + + * ly/performer-init.ly: add CueVoice to MIDI too. + + * ps/music-drawing-routines.ps: new routine BeginEPSF / + EndEPSF. + + * input/regression/markup-eps.ly: new file. + + * scm/framework-ps.scm (write-preamble): change order: vars should + be inited before procedures. + + * scm/output-ps.scm (glyph-string): break lines. 255 chars is max + for EPS files. + + * scm/define-markup-commands.scm (epsfile): add epsfile command. + +2005-04-12 Han-Wen Nienhuys + + * configure.in (gui_b): add check for ghostscript 8.15 + +2005-04-11 Han-Wen Nienhuys + + * lily/hairpin.cc (after_line_breaking): suicide the hairpinlet at + start of line. Fixes cresc-after-newline.ly + + * lily/source-file.cc (file_line_column_string): use get_column(). + +2005-04-10 Han-Wen Nienhuys + + * lily/source-file.cc (get_column): utf-8 support for column numbers. + 2005-04-12 Jan Nieuwenhuizen * lily/*: use message () iso progress_indication () for messages. @@ -50,6 +82,7 @@ * GNUmakefile.in: Bugfix: also link .map files. +>>>>>>> 1.3423 2005-04-09 Nicolas Sceaux * scm/music-functions.scm (music->make-music): generate diff --git a/GNUmakefile.in b/GNUmakefile.in index ebd654aeb7..e5f9f0cdf5 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -59,6 +59,9 @@ web-uninstall: local-install: $(INSTALL) -d $(DESTDIR)$(local_lilypond_datadir) +final-install: + @true + web-ext = html midi pdf png txt ly footify = $(PYTHON) $(step-bindir)/add-html-footer.py --name $(PACKAGE_NAME) --version $(TOPLEVEL_VERSION) diff --git a/configure.in b/configure.in index 6c43498096..71107fdde7 100644 --- a/configure.in +++ b/configure.in @@ -54,6 +54,8 @@ STEPMAKE_GUILE_DEVEL(REQUIRED, 1.6.5) STEPMAKE_MAKEINFO(REQUIRED) STEPMAKE_PYTHON_DEVEL(REQUIRED) +STEPMAKE_PATH_PROG(GHOSTSCRIPT, gs, OPTIONAL, 8.15) + STEPMAKE_PROGS(MFTRACE, mftrace, REQUIRED, 1.1.1) STEPMAKE_PATH_PROG(FONTFORGE, fontforge, REQUIRED, 20041208) diff --git a/input/regression/markup-eps.ly b/input/regression/markup-eps.ly new file mode 100644 index 0000000000..d91e074799 --- /dev/null +++ b/input/regression/markup-eps.ly @@ -0,0 +1,17 @@ +\header { + + texidoc = "The epsfile markup command reads an EPS file" + +} +\version "2.5.19" + +#(let* ((port (open-output-file "box.eps"))) + + (display "%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 5 5 105 105 +10 setlinewidth 10 10 moveto 0 90 rlineto 90 0 rlineto 0 -90 rlineto +closepath stroke" port) + + (close port)) + +{ c''4-\markup { \box \epsfile #"box.eps" } } diff --git a/input/regression/utf8.ly b/input/regression/utf-8.ly similarity index 100% rename from input/regression/utf8.ly rename to input/regression/utf-8.ly diff --git a/lily/hairpin.cc b/lily/hairpin.cc index 2c7368fa57..d4f7e8a6fb 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -19,13 +19,39 @@ #include "lookup.hh" #include "text-item.hh" + +MAKE_SCHEME_CALLBACK(Hairpin,after_line_breaking,1); +SCM +Hairpin::after_line_breaking (SCM smob) +{ + Spanner *me = dynamic_cast (unsmob_grob (smob)); + + Drul_array broken; + Drul_array bounds; + Direction d = LEFT; + do + { + bounds[d] = me->get_bound (d); + broken[d] = bounds[d]->break_status_dir () != CENTER; + } + while (flip (&d) != LEFT); + + if (broken[LEFT] + && ly_c_equal_p (bounds[RIGHT]->get_column ()->get_property ("when"), + bounds[LEFT]->get_property ("when"))) + { + me->suicide (); + } + return SCM_UNSPECIFIED; +} + + MAKE_SCHEME_CALLBACK (Hairpin, print, 1); SCM Hairpin::print (SCM smob) { - Grob *me = unsmob_grob (smob); - Spanner *spanner = dynamic_cast (me); + Spanner *me = dynamic_cast (unsmob_grob (smob)); SCM s = me->get_property ("grow-direction"); if (!is_direction (s)) @@ -42,14 +68,14 @@ Hairpin::print (SCM smob) Direction d = LEFT; do { - bounds[d] = spanner->get_bound (d); + bounds[d] = me->get_bound (d); broken[d] = bounds[d]->break_status_dir () != CENTER; } while (flip (&d) != LEFT); Grob *common = bounds[LEFT]->common_refpoint (bounds[RIGHT], X_AXIS); Drul_array x_points; - + do { Item *b = bounds[d]; diff --git a/lily/include/hairpin.hh b/lily/include/hairpin.hh index 66c41193e3..31e40f7629 100644 --- a/lily/include/hairpin.hh +++ b/lily/include/hairpin.hh @@ -18,6 +18,7 @@ struct Hairpin { public: DECLARE_SCHEME_CALLBACK (print, (SCM)); + DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM)); static bool has_interface (Grob *); }; diff --git a/lily/include/source-file.hh b/lily/include/source-file.hh index faf8e5c66b..90ec4dd710 100644 --- a/lily/include/source-file.hh +++ b/lily/include/source-file.hh @@ -53,7 +53,7 @@ public: Slice line_slice (char const *pos_str0) const; String line_string (char const *pos_str0) const; int get_column (char const *pos_str0) const; - int get_char (char const *pos_str0) const; + int get_char_of_line (char const *pos_str0) const; /* JUNKME. diff --git a/lily/source-file.cc b/lily/source-file.cc index ba61d770bd..c904838124 100644 --- a/lily/source-file.cc +++ b/lily/source-file.cc @@ -11,7 +11,14 @@ #include "config.hh" +#if HAVE_UTF8_WCHAR_H +#include /* wcrtomb */ +#else +#include /* wcrtomb */ +#endif + #include + #if HAVE_SSTREAM #include #else @@ -110,7 +117,7 @@ Source_file::init_port () int Source_file::tell () const { - return pos_str0_ - contents_str0_; + return pos_str0_ - contents_str0_; } std::istream* @@ -137,7 +144,7 @@ Source_file::file_line_column_string (char const *context_str0) const return " (" + _ ("position unknown") + ")"; else return name_string () + ":" + to_string (get_line (context_str0)) - + ":" + to_string (get_char (context_str0)); + + ":" + to_string (get_column (context_str0)); } String @@ -195,7 +202,7 @@ Source_file::line_string (char const* pos_str0) const } int -Source_file::get_char (char const *pos_str0) const +Source_file::get_char_of_line (char const *pos_str0) const { if (!contains (pos_str0)) return 0; @@ -210,17 +217,46 @@ Source_file::get_column (char const *pos_str0) const if (!contains (pos_str0)) return 0; - int ch_i = get_char (pos_str0); - String line = line_string (pos_str0); + Slice line = line_slice (pos_str0); + char const *data = to_str0 (); + Byte const *line_start = (Byte const *)data + line[LEFT]; + + int left = (Byte const*) pos_str0 - line_start; + String line_begin (line_start, left); + char const *line_chars = line_begin.to_str0(); + + int column = 0; + mbstate_t state; + + /* Initialize the state. */ + memset (&state, '\0', sizeof (state)); - int col_i = 0; - for (int i = 0; i < ch_i; i++) - if (line[i] == '\t') - col_i = (col_i / 8 + 1) * 8; - else - col_i++; + while (left > 0) + { + wchar_t multibyte[2]; + size_t thislen = mbrtowc (multibyte, line_chars, left, &state); + + /* Stop converting at invalid character; + this can mean we have read just the first part + of a valid character. */ + if (thislen == (size_t) -1) + break; + /* We want to handle embedded NUL bytes + but the return value is 0. Correct this. */ + if (thislen == 0) + thislen = 1; + + if (thislen == 1 && line_chars[0] == '\t') + column = (column / 8 + 1) * 8; + else + column ++; + + /* Advance past this character. */ + line_chars += thislen; + left -= thislen; + } - return col_i; + return column; } String @@ -229,7 +265,7 @@ Source_file::error_string (char const* pos_str0) const if (!contains (pos_str0)) return " (" + _ ("position unknown") + ")"; - int ch_i = get_char (pos_str0); + int ch_i = get_char_of_line (pos_str0); String line = line_string (pos_str0); String context = line.left_string (ch_i) + to_string ('\n') diff --git a/ly/performer-init.ly b/ly/performer-init.ly index 9c0abfa400..b1b5f2c723 100644 --- a/ly/performer-init.ly +++ b/ly/performer-init.ly @@ -37,6 +37,11 @@ \consists "Melisma_translator" } +\context { + \Voice + \name CueVoice + \alias Voice +} \context { \Voice diff --git a/ps/music-drawing-routines.ps b/ps/music-drawing-routines.ps index 3bcfa3a45f..8627ea5e11 100644 --- a/ps/music-drawing-routines.ps +++ b/ps/music-drawing-routines.ps @@ -8,7 +8,30 @@ /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse +% from adobe tech note 5002. +/BeginEPSF { %def + /b4_Inc_state save def % Save state for cleanup + /dict_count countdictstack def % Count objects on dict stack + /op_count count 1 sub def % Count objects on operand stack + userdict begin % Push userdict on dict stack + /showpage { } def % Redefine showpage, { } = null proc + 0 setgray 0 setlinecap % Prepare graphics state + 1 setlinewidth 0 setlinejoin + 10 setmiterlimit [ ] 0 setdash newpath + /languagelevel where % If level not equal to 1 then + {pop languagelevel % set strokeadjust and + 1 ne % overprint to their defaults. + {false setstrokeadjust false setoverprint + } if + } if +} bind def + +/EndEPSF { %def + count op_count sub {pop} repeat % Clean up stacks + countdictstack dict_count sub {end} repeat + b4_Inc_state restore +} bind def % llx lly urx ury URI /mark_URI diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index bc401414e9..f6a82e8ea3 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -487,6 +487,7 @@ (Hairpin . ( (print-function . ,Hairpin::print) + (after-line-breaking-callback . ,Hairpin::after_line_breaking) (thickness . 1.0) (height . 0.6666) (spacing-procedure . ,Spanner::set_spacing_rods) diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm index 4758c6603c..14de51a7ad 100644 --- a/scm/define-markup-commands.scm +++ b/scm/define-markup-commands.scm @@ -5,6 +5,7 @@ ;;;; (c) 2000--2005 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen + ;;; markup commands ;;; * each markup function should have a doc string with ;; syntax, description and example. @@ -45,6 +46,60 @@ the PDF backend." (url-expr (list 'url-link url `(quote ,xextent) `(quote ,yextent)))) (ly:stencil-add (ly:make-stencil url-expr xextent yextent) stil))) + +(define bbox-regexp + (make-regexp "%%BoundingBox: ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)")) + +(define (get-postscript-bbox string) + "Extract the bbox from STRING, or return #f if not present." + (let* + ((match (regexp-exec bbox-regexp string))) + + (if match + (map (lambda (x) + (string->number (match:substring match x))) + (cdr (iota 5))) + + #f))) + +(def-markup-command (epsfile layout props file-name) (string?) + "Inline an EPS image. The image is scaled such that 10 PS units is +one staff-space." + + (if (ly:get-option 'safe) + (interpret-markup layout props "not allowed in safe") + (let* + ((contents (ly:gulp-file file-name)) + (bbox (get-postscript-bbox contents)) + (scaled-bbox + (if bbox + (map (lambda (x) (/ x 10)) bbox) + (begin + (ly:warn (_ "Could not find bounding box of `~a'") + file-name) + '())))) + + + (if bbox + + (ly:make-stencil + (list + 'embedded-ps + (string-append + + ; adobe 5002. + "BeginEPSF " + "0.1 0.1 scale " + (format "\n%%BeginDocument: ~a\n" file-name) + contents + "%%EndDocument\n" + "EndEPSF\n" + )) + (cons (list-ref scaled-bbox 0) (list-ref scaled-bbox 2)) + (cons (list-ref scaled-bbox 1) (list-ref scaled-bbox 3))) + + (ly:make-stencil "" '(0 . 0) '(0 . 0)))))) + (def-markup-command (score layout props score) (ly:score?) "Inline an image of music." (let* ((systems (ly:score-embedded-format score layout))) diff --git a/scm/framework-ps.scm b/scm/framework-ps.scm index 34a90897fd..167ca93990 100644 --- a/scm/framework-ps.scm +++ b/scm/framework-ps.scm @@ -195,7 +195,6 @@ "%%BeginSetup\n" (define-fonts paper) (output-variables paper) - "init-lilypond-parameters\n" "%%EndSetup\n")) (define-public (munge-lily-font-name name) @@ -260,11 +259,16 @@ (filter string? font-names)))) pfas)) - (display (procset "music-drawing-routines.ps") port) - (display (procset "lilyponddefs.ps") port) (if load-fonts? (for-each (lambda (f) (display f port)) (load-fonts paper))) - (display (setup paper) port)) + (display (setup paper) port) + + ; adobe note 5002: should initialize variables before loading routines. + (display (procset "music-drawing-routines.ps") port) + (display (procset "lilyponddefs.ps") port) + (display "init-lilypond-parameters\n" port) + + ) (define-public (output-framework basename book scopes fields) (let* ((filename (format "~a.ps" basename)) diff --git a/scm/output-ps.scm b/scm/output-ps.scm index 33dbdbc9fd..ceaf44306b 100644 --- a/scm/output-ps.scm +++ b/scm/output-ps.scm @@ -186,8 +186,8 @@ (if (and (= 0.0 x) (= 0.0 y)) - (format #f " /~a glyphshow " g) - (format #f " ~a ~a rmoveto /~a glyphshow " + (format #f " /~a glyphshow\n" g) + (format #f " ~a ~a rmoveto /~a glyphshow\n" x y g)))) x-y-named-glyphs)) )) -- 2.39.5