From 26a9e9b251e5a9529e4f4e6920830f098a41e7ea Mon Sep 17 00:00:00 2001 From: Patrick McCarty Date: Sat, 1 Aug 2009 23:08:23 -0700 Subject: [PATCH] SVG backend: Output a single SVG file for each page If the SVG backend is used when creating multiple-page scores, a single SVG file is created, using the and elements to delimit individual pages. Unfortunately, these elements are not supported by any known user agent, and they are part of a W3C Working Draft (SVG Print 1.2) that might not reach recommendation status for several years. At this point in time, a better solution is to output a single SVG file for each individual page. Outputters are created and closed for every page, and the unique filename suffixes are used for each successive page. We want to *eventually* add support for and with a -d option, so the source code comments have been updated to reflect this. --- Documentation/application/running.itely | 4 +- scm/framework-svg.scm | 135 +++++++++++------------- scm/output-svg.scm | 8 -- 3 files changed, 66 insertions(+), 81 deletions(-) diff --git a/Documentation/application/running.itely b/Documentation/application/running.itely index 3d86a2856a..23ab331f3f 100644 --- a/Documentation/application/running.itely +++ b/Documentation/application/running.itely @@ -243,8 +243,8 @@ This mode is used by default by @command{lilypond-book}. for SVG (Scalable Vector Graphics). - This creates a single SVG file containing the entire music output - with no embedded fonts. It is recommended to install the Century + This creates a single SVG file, without embedded fonts, for every + page of output. It is recommended to install the Century Schoolbook fonts, included with your LilyPond installation, for optimal rendering. Under UNIX, simply copy these fonts from the LilyPond directory (typically diff --git a/scm/framework-svg.scm b/scm/framework-svg.scm index 3d03aa6e30..5418d69014 100644 --- a/scm/framework-svg.scm +++ b/scm/framework-svg.scm @@ -1,85 +1,78 @@ -;; -;; framework-svg.scm -- structure for SVG output +;;;; framework-svg.scm -- structure for SVG output ;;;; ;;;; source file of the GNU LilyPond music typesetter -;;;; +;;;; ;;;; (c) 2004--2009 Jan Nieuwenhuizen +;;;; Patrick McCarty -(define-module (scm framework-svg)) +;;;; Recommendations: +;;;; http://www.w3.org/TR/SVG11/ +;;;; http://www.w3.org/TR/SVGTiny12/ +;;;; +;;;; Working draft: +;;;; http://www.w3.org/TR/SVGPrint/ -- for and -(use-modules (guile) - (lily) - (scm page) - (scm output-svg)) +;;;; TODO: +;;;; * Once and are supported by Inkscape and +;;;; other user agents, add a -d option (-dsvg-multiple-page) +;;;; that will create a single SVG file containing all pages +;;;; of output. --pmccarty -(use-modules (srfi srfi-1) - (srfi srfi-2) - (srfi srfi-13) - (ice-9 regex)) +(define-module (scm framework-svg)) + +(use-modules + (guile) + (lily) + (scm page) + (scm output-svg) + (srfi srfi-1) + (srfi srfi-2) + (srfi srfi-13) + (ice-9 regex)) (define format ergonomic-simple-format) -(define-public (output-framework basename book scopes fields) - (let* ((filename (format "~a.svg" basename)) - (outputter (ly:make-paper-outputter (open-file filename "wb") - (ly:get-option 'backend))) - (dump (lambda (str) (display str (ly:outputter-port outputter)))) - (paper (ly:paper-book-paper book)) - (unit-length (ly:output-def-lookup paper 'output-scale)) - (output-scale (* lily-unit->mm-factor - unit-length)) +(define (svg-header paper) + (let* ((lookup (lambda (x) (ly:output-def-lookup paper x))) + (unit-length (lookup 'output-scale)) + (output-scale (* lily-unit->mm-factor unit-length)) + (paper-width (lookup 'paper-width)) + (paper-height (lookup 'paper-height)) + (page-width (* output-scale paper-width)) + (page-height (* output-scale paper-height))) + + `((xmlns . "http://www.w3.org/2000/svg") + (xmlns:xlink . "http://www.w3.org/1999/xlink") + (version . "1.2") + (width . ,(ly:format "~2fmm" page-width)) + (height . ,(ly:format "~2fmm" page-height)) + (viewBox . ,(ly:format "0 0 ~4f ~4f" + paper-width paper-height))))) + +(define (dump-page paper filename page page-number page-count) + (let* ((outputter (ly:make-paper-outputter (open-file filename "wb") 'svg)) + (dump (lambda (str) (display str (ly:outputter-port outputter))))) + + (dump (apply eo 'svg (svg-header paper))) + (dump (comment (format "Page: ~S/~S" page-number page-count))) + (ly:outputter-dump-stencil outputter page) + (dump (ec 'svg)) + (ly:outputter-close outputter))) + +(define (output-framework basename book scopes fields) + (let* ((paper (ly:paper-book-paper book)) (page-stencils (map page-stencil (ly:paper-book-pages book))) - (landscape? (eq? (ly:output-def-lookup paper 'landscape) #t)) (page-number (1- (ly:output-def-lookup paper 'first-page-number))) (page-count (length page-stencils)) - (paper-width (ly:output-def-lookup paper 'paper-width)) - (paper-height (ly:output-def-lookup paper 'paper-height)) - (page-width (* output-scale paper-width)) - (page-height (* output-scale paper-height)) - (page-set? (or (> page-count 1) landscape?))) + (filename "") + (file-suffix (lambda (num) + (if (= page-count 1) "" (format "-page-~a" num))))) - (ly:outputter-output-scheme outputter - `(begin (set! lily-unit-length ,unit-length) "")) - (dump (eo 'svg - '(xmlns . "http://www.w3.org/2000/svg") - '(xmlns:xlink . "http://www.w3.org/1999/xlink") - '(version . "1.2") - `(width . ,(ly:format "~2fmm" page-width)) - `(height . ,(ly:format "~2fmm" page-height)) - `(viewBox . ,(ly:format "0 0 ~4f ~4f" - paper-width paper-height)))) - - (dump - (string-append - ;; FIXME: only use pages if there are more than one, pageSet is - ;; not supported by all SVG applications yet. - (if page-set? (eo 'pageSet) ""))) - (for-each - (lambda (page) - (set! page-number (1+ page-number)) - (dump-page outputter page page-number page-count landscape? page-set?)) - page-stencils) - - (if page-set? (eo 'pageSet) "") - (dump - (string-append - (if page-set? (ec 'pageSet) "") - (ec 'svg))) - - (ly:outputter-close outputter) - )) - -(define (dump-page outputter page page-number page-count landscape? page-set?) - (define (dump str) (display str (ly:outputter-port outputter))) - - (dump (comment (format "Page: ~S/~S" page-number page-count))) - (if (or landscape? page-set?) - (dump - (if landscape? - (eo 'page '(page-orientation . "270")) - (eo 'page)))) - - (ly:outputter-dump-stencil outputter page) - (if (or landscape? page-set?) - (dump (ec 'page)))) + (lambda (page) + (set! page-number (1+ page-number)) + (set! filename (format "~a~a.svg" + basename + (file-suffix page-number))) + (dump-page paper filename page page-number page-count)) + page-stencils))) diff --git a/scm/output-svg.scm b/scm/output-svg.scm index c916067bdf..8a52ed6a3d 100644 --- a/scm/output-svg.scm +++ b/scm/output-svg.scm @@ -5,14 +5,6 @@ ;;;; (c) 2002--2009 Jan Nieuwenhuizen ;;;; Patrick McCarty -;;;; Recommendations: -;;;; http://www.w3.org/TR/SVG11/ -;;;; http://www.w3.org/TR/SVGTiny12/ -;;;; http://www.w3.org/TR/SVGPrint/ -- page, pageSet in draft - -;;;; TODO: -;;;; * inkscape page/pageSet support - (define-module (scm output-svg)) (define this-module (current-module)) -- 2.39.5