X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scm%2Foutput-lib.scm;h=a73e2c0324977e6046d45c8cfb736bd59ec4c644;hb=f4f75589864371d3a6c50eace36561a73203acee;hp=59f93e2e7ea3111cf4048409901273858ffed974;hpb=6847983a10f40946dfd25e97c0bedbdc8b9de2be;p=lilypond.git diff --git a/scm/output-lib.scm b/scm/output-lib.scm index 59f93e2e7e..a73e2c0324 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -1,6 +1,6 @@ ;;;; This file is part of LilyPond, the GNU music typesetter. ;;;; -;;;; Copyright (C) 1998--2014 Jan Nieuwenhuizen +;;;; Copyright (C) 1998--2015 Jan Nieuwenhuizen ;;;; Han-Wen Nienhuys ;;;; ;;;; LilyPond is free software: you can redistribute it and/or modify @@ -26,6 +26,33 @@ (define-public (grob::is-live? grob) (pair? (ly:grob-basic-properties grob))) +(define-public (grob::name grob) + "Return the name of the grob @var{grob} as a symbol." + (assq-ref (ly:grob-property grob 'meta) 'name)) + +(define-public (grob::rhythmic-location grob) + "Return a pair consisting of the measure number and moment within + the measure of grob @var{grob}." + (let* (; all grobs support either spanner- or item-interface + (item (if (grob::has-interface grob 'spanner-interface) + (ly:spanner-bound grob LEFT) + grob)) + (col (ly:item-get-column item))) + (if (ly:grob? col) + (ly:grob-property col 'rhythmic-location) + '()))) + +(define-public (grob::when grob) + "Return the global timestep (a moment) of grob @var{grob}." + (let* (; all grobs support either spanner- or item-interface + (item (if (grob::has-interface grob 'spanner-interface) + (ly:spanner-bound grob LEFT) + grob)) + (col (ly:item-get-column item))) + (if (ly:grob? col) + (ly:grob-property col 'when) + '()))) + (define-public (make-stencil-boxer thickness padding callback) "Return function that adds a box around the grob passed as argument." (lambda (grob) @@ -103,6 +130,44 @@ line-thickness)) +(define (grob::objects-from-interface grob iface) + "For grob @var{grob} return the name and contents of all properties + within interface @var{iface} having type @code{ly:grob?} or + @code{ly:grob-array?}." + (let* ((iface-entry (hashq-ref (ly:all-grob-interfaces) iface)) + (props (if iface-entry (last iface-entry) '())) + (pointer-props + (filter + (lambda (prop) + (let ((type (object-property prop 'backend-type?))) + (or (eq? type ly:grob?) + (eq? type ly:grob-array?)))) + props))) + (if (null? pointer-props) + '() + (list iface + (map + (lambda (prop) (list prop (ly:grob-object grob prop))) + pointer-props))))) + +(define-public (grob::all-objects grob) + "Return a list of the names and contents of all properties having type + @code{ly:grob?} or @code{ly:grob-array?} for all interfaces supported by + grob @var{grob}." + (let loop ((ifaces (ly:grob-interfaces grob)) (result '())) + (if (null? ifaces) + (cons grob (list result)) + (let ((entry (grob::objects-from-interface grob (car ifaces)))) + (if (pair? entry) + (loop (cdr ifaces) (append result (list entry))) + (loop (cdr ifaces) result)))))) + +(use-modules (ice-9 pretty-print)) +(define-public (grob::display-objects grob) + "Display all objects stored in properties of grob @var{grob}." + (pretty-print (grob::all-objects grob)) + (newline)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; beam slope @@ -995,7 +1060,9 @@ and duration-log @var{log}." (define-public (string-number::calc-text grob) (let ((event (event-cause grob))) (or (ly:event-property event 'text #f) - (number->string (ly:event-property event 'string-number) 10)))) + (number-format + (ly:grob-property grob 'number-type) + (ly:event-property event 'string-number))))) (define-public (stroke-finger::calc-text grob) (let ((event (event-cause grob))) @@ -1155,17 +1222,31 @@ parent or the parent has no setting." (define-public (script-interface::calc-x-offset grob) (ly:grob-property grob 'positioning-done) - (let* ((shift (ly:grob-property grob 'toward-stem-shift 0.0)) + (let* ((shift-when-alone (ly:grob-property grob 'toward-stem-shift 0.0)) + (shift-in-column (ly:grob-property grob 'toward-stem-shift-in-column)) + (script-column (ly:grob-object grob 'script-column)) + (shift + (if (and (ly:grob? script-column) + (number? shift-in-column) + ;; ScriptColumn can contain grobs other than Script. + ;; These should not result in a shift. + (any (lambda (s) + (and (not (eq? s grob)) + (grob::has-interface s 'script-interface) + (not (grob::has-interface s + 'accidental-suggestion-interface)))) + (ly:grob-array->list + (ly:grob-object script-column 'scripts)))) + shift-in-column shift-when-alone)) (note-head-location (ly:self-alignment-interface::aligned-on-x-parent grob)) (note-head-grob (ly:grob-parent grob X)) (stem-grob (ly:grob-object note-head-grob 'stem))) (+ note-head-location - ;; If the property 'toward-stem-shift is defined and the script - ;; has the same direction as the stem, move the script accordingly. - ;; Since scripts can also be over skips, we need to check whether - ;; the grob has a stem at all. + ;; If the script has the same direction as the stem, move the script + ;; in accordance with the value of 'shift'. Since scripts can also be + ;; over skips, we need to check whether the grob has a stem at all. (if (ly:grob? stem-grob) (let ((dir1 (ly:grob-property grob 'direction)) (dir2 (ly:grob-property stem-grob 'direction))) @@ -1359,6 +1440,49 @@ parent or the parent has no setting." (interval-union '(0 . 0) (cons smaller larger))) '(0 . 0)))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; measure counter + +(define-public (measure-counter-stencil grob) + "Print a number for a measure count. The number is centered using +the extents of @code{BreakAlignment} grobs associated with the left and +right bounds of a @code{MeasureCounter} spanner. Broken measures are +numbered in parentheses." + (let* ((num (markup (number->string (ly:grob-property grob 'count-from)))) + (orig (ly:grob-original grob)) + (siblings (ly:spanner-broken-into orig)) ; have we been split? + (num + (if (or (null? siblings) + (eq? grob (car siblings))) + num + (make-parenthesize-markup num))) + (num (grob-interpret-markup grob num)) + (num (ly:stencil-aligned-to num X (ly:grob-property grob 'self-alignment-X))) + (left-bound (ly:spanner-bound grob LEFT)) + (right-bound (ly:spanner-bound grob RIGHT)) + (elts-L (ly:grob-array->list (ly:grob-object left-bound 'elements))) + (elts-R (ly:grob-array->list (ly:grob-object right-bound 'elements))) + (break-alignment-L + (filter + (lambda (elt) (grob::has-interface elt 'break-alignment-interface)) + elts-L)) + (break-alignment-R + (filter + (lambda (elt) (grob::has-interface elt 'break-alignment-interface)) + elts-R)) + (refp (ly:grob-system grob)) + (break-alignment-L-ext (ly:grob-extent (car break-alignment-L) refp X)) + (break-alignment-R-ext (ly:grob-extent (car break-alignment-R) refp X)) + (num + (ly:stencil-translate-axis + num + (+ (interval-length break-alignment-L-ext) + (* 0.5 + (- (car break-alignment-R-ext) + (cdr break-alignment-L-ext)))) + X))) + num)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; make-engraver helper macro